dd: clarify meaning of multiplication factors; put xM in order
[platform/upstream/coreutils.git] / src / test.c
index d185ab4..833b254 100644 (file)
@@ -2,23 +2,20 @@
 
 /* Modified to run with the GNU shell by bfox. */
 
-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2005, 2007-2008 Free Software Foundation, Inc.
 
-   This file is part of GNU Bash, the Bourne Again SHell.
+   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.
 
-   Bash is free software; you can redistribute it and/or modify it under
-   the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
-   WARRANTY; without even the implied warranty of MERCHANTABILITY or
-   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
+   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, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Define TEST_STANDALONE to get the /bin/test version.  Otherwise, you get
    the shell builtin version. */
 #endif
 
 #include "system.h"
-#include "error.h"
 #include "euidaccess.h"
-#include "inttostr.h"
 #include "quote.h"
+#include "stat-time.h"
 #include "strnumcmp.h"
 
 #if HAVE_SYS_PARAM_H
 # include <sys/param.h>
 #endif
 
-char *program_name;
-
 /* Exit status for syntax errors, etc.  */
 enum { TEST_TRUE, TEST_FALSE, TEST_FAILURE };
 
-#if defined (TEST_STANDALONE)
+#if defined TEST_STANDALONE
 # define test_exit(val) exit (val)
 #else
    static jmp_buf test_exit_buf;
@@ -89,6 +83,7 @@ test_syntax_error (char const *format, char const *arg)
 {
   fprintf (stderr, "%s: ", argv[0]);
   fprintf (stderr, format, arg);
+  fputc ('\n', stderr);
   fflush (stderr);
   test_exit (TEST_FAILURE);
 }
@@ -132,7 +127,7 @@ find_int (char const *string)
   char const *p;
   char const *number_start;
 
-  for (p = string; ISBLANK (to_uchar (*p)); p++)
+  for (p = string; isblank (to_uchar (*p)); p++)
     continue;
 
   if (*p == '+')
@@ -150,29 +145,28 @@ find_int (char const *string)
     {
       while (ISDIGIT (*p))
        p++;
-      while (ISBLANK (to_uchar (*p)))
+      while (isblank (to_uchar (*p)))
        p++;
       if (!*p)
        return number_start;
     }
 
-  test_syntax_error (_("invalid integer %s\n"), quote (string));
+  test_syntax_error (_("invalid integer %s"), quote (string));
 }
 
-/* Find the modification time of FILE, and stuff it into *AGE.
-   If the timestamp has a nonoseconds part, stuff that into *NS;
-   otherwise stuff zero into *NS.
+/* Find the modification time of FILE, and stuff it into *MTIME.
    Return true if successful.  */
 static bool
-age_of (char const *filename, time_t *age, long *ns)
+get_mtime (char const *filename, struct timespec *mtime)
 {
   struct stat finfo;
   bool ok = (stat (filename, &finfo) == 0);
+#ifdef lint
+  static struct timespec const zero;
+  *mtime = zero;
+#endif
   if (ok)
-    {
-      *age = finfo.st_mtime;
-      *ns = TIMESPEC_NS (finfo.st_mtim);
-    }
+    *mtime = get_stat_mtime (&finfo);
   return ok;
 }
 
@@ -238,10 +232,10 @@ term (void)
 
       value = posixtest (nargs);
       if (argv[pos] == 0)
-       test_syntax_error (_("')' expected\n"), NULL);
+       test_syntax_error (_("')' expected"), NULL);
       else
         if (argv[pos][0] != ')' || argv[pos][1])
-         test_syntax_error (_("')' expected, found %s\n"), argv[pos]);
+         test_syntax_error (_("')' expected, found %s"), argv[pos]);
       advance (false);
     }
 
@@ -257,7 +251,7 @@ term (void)
       if (test_unop (argv[pos]))
        value = unary_operator ();
       else
-       test_syntax_error (_("%s: unary operator expected\n"), argv[pos]);
+       test_syntax_error (_("%s: unary operator expected"), argv[pos]);
     }
   else
     {
@@ -322,20 +316,14 @@ binary_operator (bool l_is_l)
          if (argv[op][2] == 't' && !argv[op][3])
            {
              /* nt - newer than */
-             time_t lt IF_LINT (= 0);
-             time_t rt IF_LINT (= 0);
-             long l_ns IF_LINT (= 0);
-             long r_ns IF_LINT (= 0);
+             struct timespec lt, rt;
              bool le, re;
              pos += 3;
              if (l_is_l | r_is_l)
-               test_syntax_error (_("-nt does not accept -l\n"), NULL);
-             le = age_of (argv[op - 1], &lt, &l_ns);
-             re = age_of (argv[op + 1], &rt, &r_ns);
-             if (le && re && (rt == lt))
-               return l_ns > r_ns;
-             else
-               return le > re || (le && lt > rt);
+               test_syntax_error (_("-nt does not accept -l"), NULL);
+             le = get_mtime (argv[op - 1], &lt);
+             re = get_mtime (argv[op + 1], &rt);
+             return le && (!re || timespec_cmp (lt, rt) > 0);
            }
          break;
 
@@ -345,7 +333,7 @@ binary_operator (bool l_is_l)
              /* ef - hard link? */
              pos += 3;
              if (l_is_l | r_is_l)
-               test_syntax_error (_("-ef does not accept -l\n"), NULL);
+               test_syntax_error (_("-ef does not accept -l"), NULL);
              return (stat (argv[op - 1], &stat_buf) == 0
                      && stat (argv[op + 1], &stat_spare) == 0
                      && stat_buf.st_dev == stat_spare.st_dev
@@ -357,26 +345,20 @@ binary_operator (bool l_is_l)
          if ('t' == argv[op][2] && '\000' == argv[op][3])
            {
              /* ot - older than */
-             time_t lt IF_LINT (= 0);
-             time_t rt IF_LINT (= 0);
-             long l_ns IF_LINT (= 0);
-             long r_ns IF_LINT (= 0);
+             struct timespec lt, rt;
              bool le, re;
              pos += 3;
              if (l_is_l | r_is_l)
-               test_syntax_error (_("-ot does not accept -l\n"), NULL);
-             le = age_of (argv[op - 1], &lt, &l_ns);
-             re = age_of (argv[op + 1], &rt, &r_ns);
-             if (le && re && (lt == rt))
-               return l_ns < r_ns;
-             else
-               return le < re || (re && lt < rt);
+               test_syntax_error (_("-ot does not accept -l"), NULL);
+             le = get_mtime (argv[op - 1], &lt);
+             re = get_mtime (argv[op + 1], &rt);
+             return re && (!le || timespec_cmp (lt, rt) < 0);
            }
          break;
        }
 
       /* FIXME: is this dead code? */
-      test_syntax_error (_("unknown binary operator\n"), argv[op]);
+      test_syntax_error (_("unknown binary operator"), argv[op]);
     }
 
   if (argv[op][0] == '=' && !argv[op][1])
@@ -614,7 +596,7 @@ two_arguments (void)
       if (test_unop (argv[pos]))
        value = unary_operator ();
       else
-       test_syntax_error (_("%s: unary operator expected\n"), argv[pos]);
+       test_syntax_error (_("%s: unary operator expected"), argv[pos]);
     }
   else
     beyond ();
@@ -642,7 +624,7 @@ three_arguments (void)
   else if (STREQ (argv[pos + 1], "-a") || STREQ (argv[pos + 1], "-o"))
     value = expr ();
   else
-    test_syntax_error (_("%s: binary operator expected\n"), argv[pos+1]);
+    test_syntax_error (_("%s: binary operator expected"), argv[pos+1]);
   return (value);
 }
 
@@ -691,7 +673,7 @@ posixtest (int nargs)
   return (value);
 }
 
-#if defined (TEST_STANDALONE)
+#if defined TEST_STANDALONE
 # include "long-options.h"
 
 void
@@ -784,18 +766,25 @@ Except for -h and -L, all FILE-related tests dereference symbolic links.\n\
 Beware that parentheses need to be escaped (e.g., by backslashes) for shells.\n\
 INTEGER may also be -l STRING, which evaluates to the length of STRING.\n\
 "), stdout);
+      fputs (_("\
+\n\
+NOTE: [ honors the --help and --version options, but test does not.\n\
+test treats each of those as it treats any other nonempty STRING.\n\
+"), stdout);
       printf (USAGE_BUILTIN_WARNING, _("test and/or ["));
-      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+      emit_bug_reporting_address ();
     }
   exit (status);
 }
 #endif /* TEST_STANDALONE */
 
-#if !defined (TEST_STANDALONE)
+#if !defined TEST_STANDALONE
 # define main test_command
 #endif
 
-#define AUTHORS "Kevin Braunsdorf", "Matthew Bradburn"
+#define AUTHORS \
+  proper_name ("Kevin Braunsdorf"), \
+  proper_name ("Matthew Bradburn")
 
 /*
  * [:
@@ -808,7 +797,7 @@ main (int margc, char **margv)
 {
   bool value;
 
-#if !defined (TEST_STANDALONE)
+#if !defined TEST_STANDALONE
   int code;
 
   code = setjmp (test_exit_buf);
@@ -817,7 +806,7 @@ main (int margc, char **margv)
     return (test_error_return);
 #else /* TEST_STANDALONE */
   initialize_main (&margc, &margv);
-  program_name = margv[0];
+  set_program_name (margv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
@@ -834,12 +823,12 @@ main (int margc, char **margv)
         "[" form, and when the last argument is not "]".  POSIX
         allows "[ --help" and "[ --version" to have the usual GNU
         behavior, but it requires "test --help" and "test --version"
-        to exit silently with status 1.  */
+        to exit silently with status 0.  */
       if (margc < 2 || !STREQ (margv[margc - 1], "]"))
        {
-         parse_long_options (margc, margv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
+         parse_long_options (margc, margv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
                              usage, AUTHORS, (char const *) NULL);
-         test_syntax_error (_("missing `]'\n"), NULL);
+         test_syntax_error (_("missing `]'"), NULL);
        }
 
       --margc;