⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 2 页
字号:
/* test.c - GNU test program (ksb and mjb) *//* Modified to run with the GNU shell Apr 25, 1988 by bfox. *//* Copyright (C) 1987-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 <http://www.gnu.org/licenses/>.*//* 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 <stdio.h>#include "bashtypes.h"#if !defined (HAVE_LIMITS_H)#  include <sys/param.h>#endif#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include <errno.h>#if !defined (errno)extern int errno;#endif /* !errno */#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H)#  include <sys/file.h>#endif /* !_POSIX_VERSION */#include "posixstat.h"#include "filecntl.h"#include "bashintl.h"#include "shell.h"#include "pathexp.h"#include "test.h"#include "builtins/common.h"#include <glob/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	2static procenv_t test_exit_buf;static int test_error_return;#define test_exit(val) \	do { test_error_return = val; longjmp (test_exit_buf, 1); } while (0)extern int sh_stat __P((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 __P((char *, char *)) __attribute__((__noreturn__));static void beyond __P((void)) __attribute__((__noreturn__));static void integer_expected_error __P((char *)) __attribute__((__noreturn__));static int unary_operator __P((void));static int binary_operator __P((void));static int two_arguments __P((void));static int three_arguments __P((void));static int posixtest __P((void));static int expr __P((void));static int term __P((void));static int and __P((void));static int or __P((void));static int filecomp __P((char *, char *, int));static int arithcomp __P((char *, char *, int, int));static int patcomp __P((char *, char *, int));static voidtest_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 voidbeyond (){  test_syntax_error (_("argument expected"), (char *)NULL);}/* Syntax error for when an integer argument was expected, but   something else was found. */static voidinteger_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 supressed 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 intexpr (){  if (pos >= argc)    beyond ();  return (FALSE ^ or ());		/* Same with this. */}/* * or: *	and *	and '-o' or */static intor (){  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 intand (){  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 *	'-o' option *	string *	string ('!='|'='|'==') string *	<int> '-'(eq|ne|le|lt|ge|gt) <int> *	file '-'(nt|ot|ef) file *	'(' <expr> ')' * int ::= *	positive and negative integers */static intterm (){  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 */  else if (argv[pos][0] == '-' && argv[pos][2] == '\0')    {      if (test_unop (argv[pos]))	value = unary_operator ();      else	test_syntax_error (_("%s: unary operator expected"), argv[pos]);    }  else    {      value = argv[pos][0] != '\0';      advance (0);    }  return (value);}static intfilecomp (s, t, op)     char *s, *t;     int op;{  struct stat st1, st2;  int r1, r2;  if ((r1 = sh_stat (s, &st1)) < 0)    {      if (op == EF)	return (FALSE);    }  if ((r2 = sh_stat (t, &st2)) < 0)    {      if (op == EF)	return (FALSE);    }    switch (op)    {    case OT: return (r1 < r2 || (r2 == 0 && st1.st_mtime < st2.st_mtime));    case NT: return (r1 > r2 || (r1 == 0 && st1.st_mtime > st2.st_mtime));    case EF: return (same_file (s, t, &st1, &st2));    }  return (FALSE);}static intarithcomp (s, t, op, flags)     char *s, *t;     int op, flags;{  intmax_t l, r;  int expok;  if (flags & TEST_ARITHEXP)    {      l = evalexp (s, &expok);      if (expok == 0)	return (FALSE);		/* should probably longjmp here */      r = evalexp (t, &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 intpatcomp (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));}intbinary_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 (shell_compatibility_level > 40 && flags & TEST_LOCALE)	return ((op[0] == '>') ? (strcoll (arg1, arg2) > 0) : (strcoll (arg1, arg2) < 0));      else	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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -