]> sjero.net Git - wget/blobdiff - src/init.c
[svn] Adjust bandwidth limitation sleep for the error of previous sleeps.
[wget] / src / init.c
index 609761eddaef7c2fe8965dd08a803ec48ff2ac64..62488fd20a4f03f190f1ce1eea65f89c678d3f2e 100644 (file)
@@ -839,64 +839,115 @@ cmd_directory_vector (const char *com, const char *val, void *closure)
   return 1;
 }
 
-/* Set the value stored in VAL to CLOSURE (which should point to a
-   long int), allowing several postfixes, with the following syntax
-   (regexp):
+/* Poor man's atof: handles only <digits>.<digits>.  Returns 1 on
+   success, 0 on failure.  In case of success, stores its result to
+   *DEST.  */
 
-   [0-9]+       -> bytes
-   [0-9]+[kK]   -> bytes * 1024
-   [0-9]+[mM]   -> bytes * 1024 * 1024
-   inf          -> 0
+static int
+simple_atof (const char *beg, const char *end, double *dest)
+{
+  double result = 0;
+
+  int seen_dot = 0;
+  int seen_digit = 0;
+  double divider = 1;
+
+  const char *p = beg;
+
+  while (p < end)
+    {
+      char ch = *p++;
+      if (ISDIGIT (ch))
+       {
+         if (!seen_dot)
+           result = (10 * result) + (ch - '0');
+         else
+           result += (ch - '0') / (divider *= 10);
+         seen_digit = 1;
+       }
+      else if (ch == '.')
+       {
+         if (!seen_dot)
+           seen_dot = 1;
+         else
+           return 0;
+       }
+    }
+  if (!seen_digit)
+    return 0;
+
+  *dest = result;
+  return 1;
+}
+
+/* Parse VAL as a number and set its value to CLOSURE (which should
+   point to a long int).
+
+   By default, the value is assumed to be in bytes.  If "K", "M", or
+   "G" are appended, the value is multiplied with 1<<10, 1<<20, or
+   1<<30, respectively.  Floating point values are allowed and are
+   cast to integer before use.  The idea is to be able to use things
+   like 1.5k instead of "1536".
+
+   The string "inf" is returned as 0.
+
+   In case of error, 0 is returned and memory pointed to by CLOSURE
+   remains unmodified.  */
 
-   Anything else is flagged as incorrect, and CLOSURE is unchanged.  */
 static int
 cmd_bytes (const char *com, const char *val, void *closure)
 {
-  long result;
-  long *out = (long *)closure;
-  const char *p;
+  long mult;
+  double number;
+  const char *end = val + strlen (val);
 
-  result = 0;
-  p = val;
   /* Check for "inf".  */
-  if (p[0] == 'i' && p[1] == 'n' && p[2] == 'f' && p[3] == '\0')
+  if (0 == strcmp (val, "inf"))
     {
-      *out = 0;
+      *(long *)closure = 0;
       return 1;
     }
-  /* Search for digits and construct result.  */
-  for (; *p && ISDIGIT (*p); p++)
-    result = (10 * result) + (*p - '0');
-  /* If no digits were found, or more than one character is following
-     them, bail out.  */
-  if (p == val || (*p != '\0' && *(p + 1) != '\0'))
+
+  /* Strip trailing whitespace.  */
+  while (val < end && ISSPACE (end[-1]))
+    --end;
+
+  if (val == end)
     {
-      printf (_("%s: Invalid specification `%s'\n"), com, val);
+    err:
+      fprintf (stderr, _("%s: Invalid byte value `%s'\n"), com, val);
       return 0;
     }
-  /* Search for a designator.  */
-  switch (TOLOWER (*p))
+
+  switch (TOLOWER (end[-1]))
     {
-    case '\0':
-      /* None */
-      break;
     case 'k':
-      /* Kilobytes */
-      result *= 1024;
+      --end, mult = 1L<<10;
       break;
     case 'm':
-      /* Megabytes */
-      result *= (long)1024 * 1024;
+      --end, mult = 1L<<20;
       break;
     case 'g':
-      /* Gigabytes */
-      result *= (long)1024 * 1024 * 1024;
+      --end, mult = 1L<<30;
       break;
     default:
-      printf (_("%s: Invalid specification `%s'\n"), com, val);
-      return 0;
+      /* Not a recognized suffix: assume it belongs to the number.
+        (If not, atof simple_atof will raise an error.)  */
+      mult = 1;
     }
-  *out = result;
+
+  /* Skip leading and trailing whitespace. */
+  while (val < end && ISSPACE (*val))
+    ++val;
+  while (val < end && ISSPACE (end[-1]))
+    --end;
+  if (val == end)
+    goto err;
+
+  if (!simple_atof (val, end, &number))
+    goto err;
+
+  *(long *)closure = (long)(number * mult);
   return 1;
 }
 
@@ -907,14 +958,11 @@ cmd_bytes (const char *com, const char *val, void *closure)
 static int
 cmd_time (const char *com, const char *val, void *closure)
 {
-  double result, mult, divider;
-  int seen_dot, seen_digit;
-
-  const char *p;
+  double number, mult;
   const char *end = val + strlen (val);
 
-  /* Skip trailing whitespace.  */
-  while (end > val && ISSPACE (end[-1]))
+  /* Strip trailing whitespace.  */
+  while (val < end && ISSPACE (end[-1]))
     --end;
 
   if (val == end)
@@ -936,54 +984,29 @@ cmd_time (const char *com, const char *val, void *closure)
       --end, mult = 3600;      /* hours */
       break;
     case 'd':
-      --end, mult = 86400;     /* days */
+      --end, mult = 86400.0;   /* days */
       break;
     case 'w':
-      --end, mult = 604800;    /* weeks */
+      --end, mult = 604800.0;  /* weeks */
       break;
     default:
-      /* Not a recognized suffix: treat it as part of number, and
-        assume seconds. */
+      /* Not a recognized suffix: assume it belongs to the number.
+        (If not, atof simple_atof will raise an error.)  */
       mult = 1;
     }
 
   /* Skip leading and trailing whitespace. */
   while (val < end && ISSPACE (*val))
     ++val;
-  while (val > end && ISSPACE (end[-1]))
+  while (val < end && ISSPACE (end[-1]))
     --end;
   if (val == end)
     goto err;
 
-  /* Poor man's strtod: */
-  result = 0;
-  seen_dot = seen_digit = 0;
-  divider = 1;
-
-  p = val;
-  while (p < end)
-    {
-      char ch = *p++;
-      if (ISDIGIT (ch))
-       {
-         if (!seen_dot)
-           result = (10 * result) + (ch - '0');
-         else
-           result += (ch - '0') / (divider *= 10);
-         seen_digit = 1;
-       }
-      else if (ch == '.')
-       {
-         if (!seen_dot)
-           seen_dot = 1;
-         else
-           goto err;
-       }
-    }
-  if (!seen_digit)
+  if (!simple_atof (val, end, &number))
     goto err;
-  result *= mult;
-  *(double *)closure = result;
+
+  *(double *)closure = number * mult;
   return 1;
 }
 \f