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