/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1982-2012 AT&T Intellectual Property          *
*          Copyright (c) 2020-2022 Contributors to ksh 93u+m           *
*                      and is licensed under the                       *
*                 Eclipse Public License, Version 2.0                  *
*                                                                      *
*                A copy of the License is available at                 *
*      https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html      *
*         (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d)         *
*                                                                      *
*                  David Korn <dgk@research.att.com>                   *
*                  Martijn Dekker <martijn@inlv.org>                   *
*            Johnothan King <johnothanking@protonmail.com>             *
*                                                                      *
***********************************************************************/

/*
 * tables for the test builtin [[ ... ]] and [ ... ]
 */

#include	"shopt.h"
#include	<ast.h>
#include	"defs.h"
#include	"test.h"

/*
 * This is the list of binary test and [[ ... ]] operators
 * It must be sorted in ascending ASCII order
 */

const Shtable_t shtab_testops[] =
{
		"!=",		TEST_SNE,
		"-a",		TEST_AND,
		"-ef",		TEST_EF,
		"-eq",		TEST_EQ,
		"-ge",		TEST_GE,
		"-gt",		TEST_GT,
		"-le",		TEST_LE,
		"-lt",		TEST_LT,
		"-ne",		TEST_NE,
		"-nt",		TEST_NT,
		"-o",		TEST_OR,
		"-ot",		TEST_OT,
		"<",		TEST_SLT,
		"=",		TEST_SEQ,
		"==",		TEST_SEQ,
		"=~",           TEST_REP,
		">",		TEST_SGT,
		"",		0
};

const char sh_opttest[] =
"[-1c?\n@(#)$Id: test (ksh 93u+m) 2022-07-25 $\n]"
"[--catalog?" SH_DICT "]"
"[+NAME?test, [ - evaluate expression]"
"[+DESCRIPTION?\btest\b evaluates expressions and returns its result using the "
	"exit status. Option parsing is not performed; all arguments, "
	"including \b--\b, are processed as operands. It is essential to quote "
	"expression arguments to suppress empty removal, field splitting, "
	"pathname expansion, and constructs such as redirection. If the command "
	"is invoked as \b[\b, a final \b]]\b argument is required and "
	"discarded. The evaluation of the expression depends on the number of "
	"operands, as follows:]"
"{"
	"[+0?Evaluates to false.]"
	"[+1?True if argument is not an empty string.]"
	"[+2?If first operand is \b!\b, the result is True if the second "
		"operand is an empty string. Otherwise, it is evaluated "
		"as one of the unary expressions defined below. If the "
		"unary operator is invalid and the second argument is \b--\b, "
		"then the first argument is processed as a \bgetopts\b(1) "
		"help option.]"
	"[+3?If first operand is \b!\b, the result is True if the second "
		"and third operand evaluated as a unary expression is False. "
		"Otherwise, the three operands are evaluated as one of the "
		"binary expressions listed below.]"
	"[+4?If first operand is \b!\b, the result is True if the next "
		"three operands are a valid binary expression that is False.]"
"}"
"[+?For the following unary and binary operators:]"
"{"
	"[+?If any \afile\a is a symlink, it is followed before testing, "
		"except for \b-L\b/\b-h\b"
#if SHOPT_TEST_L
		"/\b-l\b"
#endif
		".]"
	"[+?If any \afile\a is of the form \b/dev/fd/\b\an\a, "
		"then file descriptor \an\a is checked.]"
	"[+?Operators marked with a * are not part of the POSIX standard.]"
"}"
"[+UNARY OPERATORS?These evaluate as True if:]{"
	"[+-a \afile\a *?Deprecated. Same as \b-e\b.]"
	"[+-b \afile\a?\afile\a is a block special file.]"
	"[+-c \afile\a?\afile\a is a character special file.]"
	"[+-d \afile\a?\afile\a is a directory.]"
	"[+-e \afile\a?\afile\a exists and is not a broken symlink.]"
	"[+-f \afile\a?\afile\a is a regular file.]"
	"[+-g \afile\a?\afile\a has its set-group-id bit set.]"
	"[+-k \afile\a *?\afile\a has its sticky bit on.]"
	"[+-n \astring\a?Length of \astring\a is non-zero.]"
	"[+-o \aoption\a *?Shell option \aoption\a is enabled.]"
	"[+-p \afile\a?\afile\a is a FIFO.]"
	"[+-r \afile\a?\afile\a is readable.]"
	"[+-s \afile\a?\afile\a has size > 0.]"
	"[+-t \anum\a?File descriptor number \anum\a is "
		"open and associated with a terminal.]"
	"[+-u \afile\a?\afile\a has its set-user-id bit set.]"
	"[+-v \avarname\a *?The variable \avarname\a is set.]"
	"[+-w \afile\a?\afile\a is writable.]"
	"[+-x \afile\a?\afile\a is executable, or if directory, searchable.]"
	"[+-z \astring\a?\astring\a is a zero-length string.]"
	"[+-G \afile\a *?Group of \afile\a is the effective "
		"group ID of the current process.]"
#if SHOPT_TEST_L
	"[+-L|l|h \afile\a?\afile\a is a symbolic link.]"
#else
	"[+-L|h \afile\a?\afile\a is a symbolic link.]"
#endif
	"[+-N \afile\a *?\afile\a has been modified since it was last read.]"
	"[+-O \afile\a *?\afile\a exists and owner is the effective "
		"user ID of the current process.]"
	"[+-R \avarname\a *?\avarname\a is a name reference.]"
	"[+-S \afile\a?\afile\a is a socket.]"
"}"
"[+BINARY OPERATORS?These evaluate as True if:]{"
	"[+\astring1\a = \astring2\a?\astring1\a is equal to \astring2\a.]"
	"[+\astring1\a == \astring2\a *?Same as \b=\b.]"
	"[+\astring1\a != \astring2\a?\astring1\a is not equal to \astring2\a.]"
	"[+\astring1\a =~ \aere\a *?\astring1\a matches the extended regular expression \aere\a.]"
	"[+\astring1\a \\< \astring2\a *?\astring1\a lexically sorts before \astring2\a.]"
	"[+\astring1\a \\> \astring2\a *?\astring1\a lexically sorts after \astring2\a.]"
	"[+\anum1\a -eq \anum2\a?\anum1\a is numerically equal to \anum2\a.]"
	"[+\anum1\a -ne \anum2\a?\anum1\a is not numerically equal to \anum2\a.]"
	"[+\anum1\a -lt \anum2\a?\anum1\a is less than \anum2\a.]"
	"[+\anum1\a -le \anum2\a?\anum1\a is less than or equal to \anum2\a.]"
	"[+\anum1\a -gt \anum2\a?\anum1\a is greater than \anum2\a.]"
	"[+\anum1\a -ge \anum2\a?\anum1\a is greater than or equal to \anum2\a.]"
	"[+\afile1\a -nt \afile2\a *?\afile1\a is newer than \afile2\a, "
		"or \afile1\a exists and \afile2\a does not.]"
	"[+\afile1\a -ot \afile2\a *?\afile1\a is older than \afile2\a, "
		"or \afile1\a does not exist and \afile2\a does.]"
	"[+\afile1\a -ef \afile2\a *?\afile1\a is a hard link or "
		"symbolic link to \afile2\a.]"
"}"
"\n"
"\nexpression\n"
"\n"
"[+EXIT STATUS?]{"
	"[+0?The expression evaluated as True.]"
	"[+1?The expression evaluated as False.]"
	"[+>1?An error occurred.]"
"}"

"[+SEE ALSO?\blet\b(1), \bexpr\b(1)]"
;

const char test_opchars[]	= "HLNRSVOGCaeohrwxdcbfugkv"
#if SHOPT_TEST_L
	"l"
#endif
				"psnzt";
const char e_argument[]		= "argument expected";
const char e_missing[]		= "%s missing";
const char e_badop[]		= "%s: unknown operator";
const char e_tstbegin[]		= "[[ ! ";
const char e_tstend[]		= " ]]\n";
