]> sjero.net Git - wget/blobdiff - src/utils.c
[svn] Allow match_tail to be case insensitive.
[wget] / src / utils.c
index cd1e645d42e7968ec4eb5d8dfdf5d9400b818e5a..46f4d2593e01d10553570762cd0f5e7ebd950331 100644 (file)
@@ -554,6 +554,22 @@ file_non_directory_p (const char *path)
   return S_ISDIR (buf.st_mode) ? 0 : 1;
 }
 
+/* Return the size of file named by FILENAME, or -1 if it cannot be
+   opened or seeked into. */
+long
+file_size (const char *filename)
+{
+  long size;
+  /* We use fseek rather than stat to determine the file size because
+     that way we can also verify whether the file is readable.
+     Inspired by the POST patch by Arnaud Wylie.  */
+  FILE *fp = fopen (filename, "rb");
+  fseek (fp, 0, SEEK_END);
+  size = ftell (fp);
+  fclose (fp);
+  return size;
+}
+
 /* Return a unique filename, given a prefix and count */
 static char *
 unique_name_1 (const char *fileprefix, int count)
@@ -739,20 +755,37 @@ accdir (const char *directory, enum accd flags)
   return 1;
 }
 
-/* Match the end of STRING against PATTERN.  For instance:
+/* Return non-zero if STRING ends with TAIL.  For instance:
+
+   match_tail ("abc", "bc", 0)  -> 1
+   match_tail ("abc", "ab", 0)  -> 0
+   match_tail ("abc", "abc", 0) -> 1
+
+   If FOLD_CASE_P is non-zero, the comparison will be
+   case-insensitive.  */
 
-   match_backwards ("abc", "bc") -> 1
-   match_backwards ("abc", "ab") -> 0
-   match_backwards ("abc", "abc") -> 1 */
 int
-match_tail (const char *string, const char *pattern)
+match_tail (const char *string, const char *tail, int fold_case_p)
 {
   int i, j;
 
-  for (i = strlen (string), j = strlen (pattern); i >= 0 && j >= 0; i--, j--)
-    if (string[i] != pattern[j])
-      break;
-  /* If the pattern was exhausted, the match was succesful.  */
+  /* We want this to be fast, so we code two loops, one with
+     case-folding, one without. */
+
+  if (!fold_case_p)
+    {
+      for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
+       if (string[i] != tail[j])
+         break;
+    }
+  else
+    {
+      for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
+       if (TOLOWER (string[i]) != TOLOWER (tail[j]))
+         break;
+    }
+
+  /* If the tail was exhausted, the match was succesful.  */
   if (j == -1)
     return 1;
   else
@@ -781,7 +814,7 @@ in_acclist (const char *const *accepts, const char *s, int backward)
        {
          if (backward)
            {
-             if (match_tail (s, *accepts))
+             if (match_tail (s, *accepts, 0))
                return 1;
            }
          else
@@ -1331,6 +1364,12 @@ numdigit (long number)
   return cnt;
 }
 
+/* A half-assed implementation of INT_MAX on machines that don't
+   bother to define one. */
+#ifndef INT_MAX
+# define INT_MAX ((int) ~((unsigned)1 << 8 * sizeof (int) - 1))
+#endif
+
 #define ONE_DIGIT(figure) *p++ = n / (figure) + '0'
 #define ONE_DIGIT_ADVANCE(figure) (ONE_DIGIT (figure), n %= (figure))
 
@@ -1390,6 +1429,15 @@ number_to_string (char *buffer, long number)
 
   if (n < 0)
     {
+      if (n < -INT_MAX)
+       {
+         /* We cannot print a '-' and assign -n to n because -n would
+            overflow.  Let sprintf deal with this border case.  */
+         sprintf (buffer, "%ld", n);
+         p += strlen (buffer);
+         return p;
+       }
+
       *p++ = '-';
       n = -n;
     }
@@ -1781,8 +1829,9 @@ debug_test_md5 (char *buf)
 \f
 /* Implementation of run_with_timeout, a generic timeout handler for
    systems with Unix-like signal handling.  */
-#ifdef HAVE_SIGSETJMP
-#define SETJMP(env) sigsetjmp (env, 1)
+#ifdef USE_SIGNAL_TIMEOUT
+# ifdef HAVE_SIGSETJMP
+#  define SETJMP(env) sigsetjmp (env, 1)
 
 static sigjmp_buf run_with_timeout_env;
 
@@ -1792,8 +1841,8 @@ abort_run_with_timeout (int sig)
   assert (sig == SIGALRM);
   siglongjmp (run_with_timeout_env, -1);
 }
-#else  /* not HAVE_SIGSETJMP */
-#define SETJMP(env) setjmp (env)
+# else /* not HAVE_SIGSETJMP */
+#  define SETJMP(env) setjmp (env)
 
 static jmp_buf run_with_timeout_env;
 
@@ -1811,7 +1860,8 @@ abort_run_with_timeout (int sig)
   /* Now it's safe to longjump. */
   longjmp (run_with_timeout_env, -1);
 }
-#endif /* not HAVE_SIGSETJMP */
+# endif /* not HAVE_SIGSETJMP */
+#endif /* USE_SIGNAL_TIMEOUT */
 
 int
 run_with_timeout (long timeout, void (*fun) (void *), void *arg)