1 /* GNU test program (ksb and mjb) */
3 /* Modified to run with the GNU shell by bfox. */
5 /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
7 This file is part of GNU Bash, the Bourne Again SHell.
9 Bash is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 /* Define TEST_STANDALONE to get the /bin/test version. Otherwise, you get
24 the shell builtin version. */
25 /* #define TEST_STANDALONE */
29 #include <sys/types.h>
31 /* The official name of this program (e.g., no `g' prefix). */
32 #define PROGRAM_NAME "test"
34 #define TEST_STANDALONE 1
36 #if !defined (TEST_STANDALONE)
38 # include "posixstat.h"
39 # include "filecntl.h"
40 #else /* TEST_STANDALONE */
42 # include "group-member.h"
44 # if !defined (S_IXUGO)
47 # if defined (_POSIX_VERSION)
49 # else /* !_POSIX_VERSION */
50 # include <sys/param.h>
51 # endif /* _POSIX_VERSION */
52 # define whitespace(c) (((c) == ' ') || ((c) == '\t'))
53 # define digit(c) ((c) >= '0' && (c) <= '9')
54 # define digit_value(c) ((c) - '0')
56 #endif /* TEST_STANDALONE */
58 #if !defined (_POSIX_VERSION)
59 # include <sys/file.h>
60 #endif /* !_POSIX_VERSION */
68 #define STREQ(a, b) ((a)[0] == (b)[0] && strcmp (a, b) == 0)
71 # define member(c, s) ((c) ? (strchr ((s), (c)) ? 1 : 0) : 0)
74 extern gid_t
getegid ();
75 extern uid_t
geteuid ();
84 /* This name is used solely when printing --version information. */
85 #define PROGRAM_NAME "test"
87 /* The following few defines control the truth and false output of each stage.
88 TRUE and FALSE are what we use to compute the final output value.
89 SHELL_BOOLEAN is the form which returns truth or falseness in shell terms.
90 TRUTH_OR is how to do logical or with TRUE and FALSE.
91 TRUTH_AND is how to do logical and with TRUE and FALSE..
92 Default is TRUE = 1, FALSE = 0, TRUTH_OR = a | b, TRUTH_AND = a & b,
93 SHELL_BOOLEAN = (!value). */
96 #define SHELL_BOOLEAN(value) (!(value))
97 #define TRUTH_OR(a, b) ((a) | (b))
98 #define TRUTH_AND(a, b) ((a) & (b))
100 #if defined (TEST_STANDALONE)
101 # define test_exit(val) exit (val)
103 static jmp_buf test_exit_buf
;
104 static int test_error_return
= 0;
105 # define test_exit(val) test_error_return = val, longjmp (test_exit_buf, 1)
106 #endif /* !TEST_STANDALONE */
108 static int pos
; /* The offset of the current argument in ARGV. */
109 static int argc
; /* The number of arguments present in ARGV. */
110 static char **argv
; /* The argument list. */
112 static int unop
PARAMS ((int op
));
113 static int binop
PARAMS ((char *s
));
114 static int unary_operator
PARAMS ((void));
115 static int binary_operator
PARAMS ((void));
116 static int two_arguments
PARAMS ((void));
117 static int three_arguments
PARAMS ((void));
118 static int posixtest
PARAMS ((void));
120 static int expr
PARAMS ((void));
121 static int term
PARAMS ((void));
122 static int and PARAMS ((void));
123 static int or PARAMS ((void));
125 static void test_syntax_error
PARAMS ((char const *format
, char const *arg
))
127 static void beyond
PARAMS ((void)) ATTRIBUTE_NORETURN
;
130 test_syntax_error (char const *format
, char const *arg
)
132 fprintf (stderr
, "%s: ", argv
[0]);
133 fprintf (stderr
, format
, arg
);
135 test_exit (SHELL_BOOLEAN (FALSE
));
138 /* A wrapper for stat () which disallows pathnames that are empty strings. */
140 test_stat (char *path
, struct stat
*finfo
)
147 return (stat (path
, finfo
));
150 /* Do the same thing access(2) does, but use the effective uid and gid,
151 and don't make the mistake of telling root that any file is executable.
152 But this loses when the containing filesystem is mounted e.g. read-only. */
154 eaccess (char *path
, int mode
)
157 static int euid
= -1;
159 if (test_stat (path
, &st
) < 0)
167 /* Root can read or write any file. */
171 /* Root can execute any file that has any one of the execute
173 if (st
.st_mode
& S_IXUGO
)
177 if (st
.st_uid
== euid
) /* owner */
179 else if (group_member (st
.st_gid
))
182 if (st
.st_mode
& mode
)
188 /* Increment our position in the argument list. Check that we're not
189 past the end of the argument list. This check is supressed if the
190 argument is FALSE. Made a macro for efficiency. */
195 if ((f) && pos >= argc) \
200 #if !defined (advance)
206 if (f
&& pos
>= argc
)
211 #define unary_advance() \
220 * beyond - call when we're beyond the end of the argument list (an
226 test_syntax_error (_("argument expected\n"), NULL
);
229 /* Syntax error for when an integer argument was expected, but
230 something else was found. */
232 integer_expected_error (char const *pch
)
234 test_syntax_error (_("integer expression expected %s\n"), pch
);
237 /* Return nonzero if the characters pointed to by STRING constitute a
238 valid number. Stuff the converted number into RESULT if RESULT is
241 isint (register char *string
, intmax_t *result
)
252 /* Skip leading whitespace characters. */
253 while (whitespace (*string
))
259 /* We allow leading `-' or `+'. */
260 if (*string
== '-' || *string
== '+')
262 if (!digit (string
[1]))
271 while (digit (*string
))
274 value
= (value
* 10) + digit_value (*string
);
278 /* Skip trailing whitespace, if any. */
279 while (whitespace (*string
))
282 /* Error if not at end of string. */
295 /* Find the modification time of FILE, and stuff it into *AGE.
296 Return 0 if successful, -1 if not. */
298 age_of (char *filename
, time_t *age
)
301 int r
= test_stat (filename
, &finfo
);
303 *age
= finfo
.st_mtime
;
308 * term - parse a term and return 1 or 0 depending on whether the term
309 * evaluates to true or false, respectively.
312 * '-'('h'|'d'|'f'|'r'|'s'|'w'|'c'|'b'|'p'|'u'|'g'|'k') filename
313 * '-'('L'|'x') filename
315 * '-'('z'|'n') string
317 * string ('!='|'=') string
318 * <int> '-'(eq|ne|le|lt|ge|gt) <int>
319 * file '-'(nt|ot|ef) file
323 * positive and negative integers
333 /* Deal with leading "not"'s. */
334 if ('!' == argv
[pos
][0] && '\000' == argv
[pos
][1])
337 while (pos
< argc
&& '!' == argv
[pos
][0] && '\000' == argv
[pos
][1])
343 return (value
^ (term ()));
346 /* A paren-bracketed argument. */
347 if (argv
[pos
][0] == '(' && !argv
[pos
][1])
352 test_syntax_error (_("')' expected\n"), NULL
);
354 if (argv
[pos
][0] != ')' || argv
[pos
][1])
355 test_syntax_error (_("')' expected, found %s\n"), argv
[pos
]);
357 return (TRUE
== (value
));
360 /* are there enough arguments left that this could be dyadic? */
361 if (((pos
+ 3 <= argc
) && binop (argv
[pos
+ 1])) ||
362 ((pos
+ 4 <= argc
&& STREQ (argv
[pos
], "-l") && binop (argv
[pos
+ 2]))))
363 value
= binary_operator ();
365 /* Might be a switch type argument */
366 else if ('-' == argv
[pos
][0] && argv
[pos
][1] && 0 == argv
[pos
][2])
368 if (unop (argv
[pos
][1]))
369 value
= unary_operator ();
371 test_syntax_error (_("%s: unary operator expected\n"), argv
[pos
]);
375 value
= (argv
[pos
][0] != '\0');
383 binary_operator (void)
386 struct stat stat_buf
, stat_spare
;
389 /* Are the left and right integer expressions of the form '-l string'? */
392 if (strcmp (argv
[pos
], "-l") == 0)
397 /* Make sure that OP is still a valid binary operator. */
398 if ((op
>= argc
- 1) || (binop (argv
[op
]) == 0))
399 test_syntax_error (_("%s: binary operator expected\n"), argv
[op
]);
409 if ((op
< argc
- 2) && (strcmp (argv
[op
+ 1], "-l") == 0))
417 if (argv
[op
][0] == '-')
419 /* check for eq, nt, and stuff */
426 if (argv
[op
][2] == 't' && !argv
[op
][3])
430 l
= strlen (argv
[op
- 1]);
433 if (!isint (argv
[op
- 1], &l
))
434 integer_expected_error (_("before -lt"));
438 r
= strlen (argv
[op
+ 2]);
441 if (!isint (argv
[op
+ 1], &r
))
442 integer_expected_error (_("after -lt"));
445 return (TRUE
== (l
< r
));
448 if (argv
[op
][2] == 'e' && !argv
[op
][3])
452 l
= strlen (argv
[op
- 1]);
455 if (!isint (argv
[op
- 1], &l
))
456 integer_expected_error (_("before -le"));
459 r
= strlen (argv
[op
+ 2]);
462 if (!isint (argv
[op
+ 1], &r
))
463 integer_expected_error (_("after -le"));
466 return (TRUE
== (l
<= r
));
471 if (argv
[op
][2] == 't' && !argv
[op
][3])
473 /* gt integer greater than */
475 l
= strlen (argv
[op
- 1]);
478 if (!isint (argv
[op
- 1], &l
))
479 integer_expected_error (_("before -gt"));
482 r
= strlen (argv
[op
+ 2]);
485 if (!isint (argv
[op
+ 1], &r
))
486 integer_expected_error (_("after -gt"));
489 return (TRUE
== (l
> r
));
492 if (argv
[op
][2] == 'e' && !argv
[op
][3])
494 /* ge - integer greater than or equal to */
496 l
= strlen (argv
[op
- 1]);
499 if (!isint (argv
[op
- 1], &l
))
500 integer_expected_error (_("before -ge"));
503 r
= strlen (argv
[op
+ 2]);
506 if (!isint (argv
[op
+ 1], &r
))
507 integer_expected_error (_("after -ge"));
510 return (TRUE
== (l
>= r
));
515 if (argv
[op
][2] == 't' && !argv
[op
][3])
517 /* nt - newer than */
521 if (l_is_l
|| r_is_l
)
522 test_syntax_error (_("-nt does not accept -l\n"), NULL
);
523 le
= age_of (argv
[op
- 1], <
);
524 re
= age_of (argv
[op
+ 1], &rt
);
525 return le
> re
|| (le
== 0 && lt
> rt
);
528 if (argv
[op
][2] == 'e' && !argv
[op
][3])
530 /* ne - integer not equal */
532 l
= strlen (argv
[op
- 1]);
535 if (!isint (argv
[op
- 1], &l
))
536 integer_expected_error (_("before -ne"));
539 r
= strlen (argv
[op
+ 2]);
542 if (!isint (argv
[op
+ 1], &r
))
543 integer_expected_error (_("after -ne"));
546 return (TRUE
== (l
!= r
));
551 if (argv
[op
][2] == 'q' && !argv
[op
][3])
553 /* eq - integer equal */
555 l
= strlen (argv
[op
- 1]);
558 if (!isint (argv
[op
- 1], &l
))
559 integer_expected_error (_("before -eq"));
562 r
= strlen (argv
[op
+ 2]);
565 if (!isint (argv
[op
+ 1], &r
))
566 integer_expected_error (_("after -eq"));
569 return (TRUE
== (l
== r
));
572 if (argv
[op
][2] == 'f' && !argv
[op
][3])
574 /* ef - hard link? */
576 if (l_is_l
|| r_is_l
)
577 test_syntax_error (_("-ef does not accept -l\n"), NULL
);
578 if (stat (argv
[op
- 1], &stat_buf
) < 0)
580 if (stat (argv
[op
+ 1], &stat_spare
) < 0)
583 (stat_buf
.st_dev
== stat_spare
.st_dev
&&
584 stat_buf
.st_ino
== stat_spare
.st_ino
));
589 if ('t' == argv
[op
][2] && '\000' == argv
[op
][3])
591 /* ot - older than */
595 if (l_is_l
|| r_is_l
)
596 test_syntax_error (_("-ot does not accept -l\n"), NULL
);
597 le
= age_of (argv
[op
- 1], <
);
598 re
= age_of (argv
[op
+ 1], &rt
);
599 return le
< re
|| (re
== 0 && lt
< rt
);
603 test_syntax_error (_("unknown binary operator"), argv
[op
]);
606 if (argv
[op
][0] == '=' && !argv
[op
][1])
608 value
= (strcmp (argv
[pos
], argv
[pos
+ 2]) == 0);
610 return (TRUE
== value
);
613 if (strcmp (argv
[op
], "!=") == 0)
615 value
= (strcmp (argv
[pos
], argv
[pos
+ 2]) != 0);
617 return (TRUE
== value
);
625 unary_operator (void)
628 struct stat stat_buf
;
630 switch (argv
[pos
][1])
635 /* All of the following unary operators use unary_advance (), which
636 checks to make sure that there is an argument, and then advances
637 pos right past it. This means that pos - 1 is the location of the
640 case 'a': /* file exists in the file system? */
643 value
= -1 != test_stat (argv
[pos
- 1], &stat_buf
);
644 return (TRUE
== value
);
646 case 'r': /* file is readable? */
648 value
= -1 != eaccess (argv
[pos
- 1], R_OK
);
649 return (TRUE
== value
);
651 case 'w': /* File is writable? */
653 value
= -1 != eaccess (argv
[pos
- 1], W_OK
);
654 return (TRUE
== value
);
656 case 'x': /* File is executable? */
658 value
= -1 != eaccess (argv
[pos
- 1], X_OK
);
659 return (TRUE
== value
);
661 case 'O': /* File is owned by you? */
663 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
666 return (TRUE
== (geteuid () == stat_buf
.st_uid
));
668 case 'G': /* File is owned by your group? */
670 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
673 return (TRUE
== (getegid () == stat_buf
.st_gid
));
675 case 'f': /* File is a file? */
677 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
680 /* Under POSIX, -f is true if the given file exists
681 and is a regular file. */
682 return (TRUE
== ((S_ISREG (stat_buf
.st_mode
)) ||
683 (0 == (stat_buf
.st_mode
& S_IFMT
))));
685 case 'd': /* File is a directory? */
687 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
690 return (TRUE
== (S_ISDIR (stat_buf
.st_mode
)));
692 case 's': /* File has something in it? */
694 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
697 return (TRUE
== (stat_buf
.st_size
> (off_t
) 0));
699 case 'S': /* File is a socket? */
700 #if !defined (S_ISSOCK)
705 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
708 return (TRUE
== (S_ISSOCK (stat_buf
.st_mode
)));
709 #endif /* S_ISSOCK */
711 case 'c': /* File is character special? */
713 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
716 return (TRUE
== (S_ISCHR (stat_buf
.st_mode
)));
718 case 'b': /* File is block special? */
720 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
723 return (TRUE
== (S_ISBLK (stat_buf
.st_mode
)));
725 case 'p': /* File is a named pipe? */
730 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
732 return (TRUE
== (S_ISFIFO (stat_buf
.st_mode
)));
733 #endif /* S_ISFIFO */
735 case 'L': /* Same as -h */
738 case 'h': /* File is a symbolic link? */
743 /* An empty filename is not a valid pathname. */
744 if ((argv
[pos
- 1][0] == '\0') ||
745 (lstat (argv
[pos
- 1], &stat_buf
) < 0))
748 return (TRUE
== (S_ISLNK (stat_buf
.st_mode
)));
751 case 'u': /* File is setuid? */
756 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
759 return (TRUE
== (0 != (stat_buf
.st_mode
& S_ISUID
)));
762 case 'g': /* File is setgid? */
767 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
770 return (TRUE
== (0 != (stat_buf
.st_mode
& S_ISGID
)));
773 case 'k': /* File has sticky bit set? */
775 if (test_stat (argv
[pos
- 1], &stat_buf
) < 0)
778 /* This is not Posix, and is not defined on some Posix systems. */
781 return (TRUE
== (0 != (stat_buf
.st_mode
& S_ISVTX
)));
784 case 't': /* File (fd) is a terminal? */
790 if (!isint (argv
[pos
], &fd
))
791 integer_expected_error (_("after -t"));
798 return (TRUE
== (fd
== (int) fd
&& isatty (fd
)));
801 case 'n': /* True if arg has some length. */
803 return (TRUE
== (argv
[pos
- 1][0] != 0));
805 case 'z': /* True if arg has no length. */
807 return (TRUE
== (argv
[pos
- 1][0] == '\0'));
822 while ((pos
< argc
) && strcmp (argv
[pos
], "-a") == 0)
825 value
= TRUTH_AND (value
, and ());
827 return (TRUE
== value
);
842 while ((pos
< argc
) && strcmp (argv
[pos
], "-o") == 0)
845 value
= TRUTH_OR (value
, or ());
848 return (TRUE
== value
);
861 return (FALSE
^ (or ())); /* Same with this. */
864 /* Return TRUE if S is one of the test command's binary operators. */
868 return ((STREQ (s
, "=")) || (STREQ (s
, "!=")) || (STREQ (s
, "-nt")) ||
869 (STREQ (s
, "-ot")) || (STREQ (s
, "-ef")) || (STREQ (s
, "-eq")) ||
870 (STREQ (s
, "-ne")) || (STREQ (s
, "-lt")) || (STREQ (s
, "-le")) ||
871 (STREQ (s
, "-gt")) || (STREQ (s
, "-ge")));
874 /* Return nonzero if OP is one of the test command's unary operators. */
878 return (member (op
, "abcdefgkLhprsStuwxOGnz"));
882 one_argument (const char *s
)
885 return (TRUE
== (isatty (1)));
887 return strlen (s
) != 0;
895 if (STREQ (argv
[pos
], "!"))
896 value
= ! one_argument (argv
[pos
+1]);
897 else if (argv
[pos
][0] == '-'
898 && argv
[pos
][1] != '\0'
899 && argv
[pos
][2] == '\0')
901 if (unop (argv
[pos
][1]))
902 value
= unary_operator ();
904 test_syntax_error (_("%s: unary operator expected\n"), argv
[pos
]);
912 three_arguments (void)
916 if (STREQ (argv
[pos
], "!"))
919 value
= !two_arguments ();
921 else if (binop (argv
[pos
+1]))
923 value
= binary_operator ();
926 else if ((STREQ (argv
[pos
+1], "-a")) || (STREQ (argv
[pos
+1], "-o")) ||
927 (argv
[pos
][0] == '('))
930 test_syntax_error (_("%s: binary operator expected\n"), argv
[pos
+1]);
934 /* This is an implementation of a Posix.2 proposal by David Korn. */
940 switch (argc
- 1) /* one extra passed in */
948 value
= one_argument (argv
[1]);
953 value
= two_arguments ();
958 value
= three_arguments ();
962 if (STREQ (argv
[pos
], "!"))
965 value
= !three_arguments ();
977 #if defined (TEST_STANDALONE)
978 # include "long-options.h"
979 # include "closeout.h"
985 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
990 Usage: %s EXPRESSION\n\
991 or: [ EXPRESSION ]\n\
994 program_name
, program_name
);
996 Exit with the status determined by EXPRESSION.\n\
999 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
1000 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
1003 EXPRESSION is true or false and sets exit status. It is one of:\n\
1007 ( EXPRESSION ) EXPRESSION is true\n\
1008 ! EXPRESSION EXPRESSION is false\n\
1009 EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true\n\
1010 EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true\n\
1014 [-n] STRING the length of STRING is nonzero\n\
1015 -z STRING the length of STRING is zero\n\
1016 STRING1 = STRING2 the strings are equal\n\
1017 STRING1 != STRING2 the strings are not equal\n\
1021 INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2\n\
1022 INTEGER1 -ge INTEGER2 INTEGER1 is greater than or equal to INTEGER2\n\
1023 INTEGER1 -gt INTEGER2 INTEGER1 is greater than INTEGER2\n\
1024 INTEGER1 -le INTEGER2 INTEGER1 is less than or equal to INTEGER2\n\
1025 INTEGER1 -lt INTEGER2 INTEGER1 is less than INTEGER2\n\
1026 INTEGER1 -ne INTEGER2 INTEGER1 is not equal to INTEGER2\n\
1030 FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers\n\
1031 FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2\n\
1032 FILE1 -ot FILE2 FILE1 is older than FILE2\n\
1036 -b FILE FILE exists and is block special\n\
1037 -c FILE FILE exists and is character special\n\
1038 -d FILE FILE exists and is a directory\n\
1039 -e FILE FILE exists\n\
1042 -f FILE FILE exists and is a regular file\n\
1043 -g FILE FILE exists and is set-group-ID\n\
1044 -h FILE FILE exists and is a symbolic link (same as -L)\n\
1045 -G FILE FILE exists and is owned by the effective group ID\n\
1046 -k FILE FILE exists and has its sticky bit set\n\
1049 -L FILE FILE exists and is a symbolic link (same as -h)\n\
1050 -O FILE FILE exists and is owned by the effective user ID\n\
1051 -p FILE FILE exists and is a named pipe\n\
1052 -r FILE FILE exists and is readable\n\
1053 -s FILE FILE exists and has a size greater than zero\n\
1056 -S FILE FILE exists and is a socket\n\
1057 -t [FD] file descriptor FD (stdout by default) is opened on a terminal\n\
1058 -u FILE FILE exists and its set-user-ID bit is set\n\
1059 -w FILE FILE exists and is writable\n\
1060 -x FILE FILE exists and is executable\n\
1064 Beware that parentheses need to be escaped (e.g., by backslashes) for shells.\n\
1065 INTEGER may also be -l STRING, which evaluates to the length of STRING.\n\
1067 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
1071 #endif /* TEST_STANDALONE */
1073 #if !defined (TEST_STANDALONE)
1074 # define main test_command
1077 #define AUTHORS N_ ("FIXME: ksb and mjb")
1086 main (int margc
, char **margv
)
1090 #if !defined (TEST_STANDALONE)
1093 code
= setjmp (test_exit_buf
);
1096 return (test_error_return
);
1097 #else /* TEST_STANDALONE */
1098 program_name
= margv
[0];
1099 setlocale (LC_ALL
, "");
1100 bindtextdomain (PACKAGE
, LOCALEDIR
);
1101 textdomain (PACKAGE
);
1103 atexit (close_stdout
);
1104 #endif /* TEST_STANDALONE */
1108 if (margv
[0] && strcmp (margv
[0], "[") == 0)
1110 /* Don't recognize --help or --version if POSIXLY_CORRECT is set. */
1111 if (getenv ("POSIXLY_CORRECT") == NULL
)
1112 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
1118 test_exit (SHELL_BOOLEAN (FALSE
));
1120 if (margv
[margc
] && strcmp (margv
[margc
], "]") != 0)
1121 test_syntax_error (_("missing `]'\n"), NULL
);
1128 test_exit (SHELL_BOOLEAN (FALSE
));
1130 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
1132 value
= posixtest ();
1135 test_syntax_error (_("too many arguments\n"), NULL
);
1137 test_exit (SHELL_BOOLEAN (value
));