Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.21
diff -u -r1.21 form.inc
--- includes/form.inc	23 Nov 2005 16:21:12 -0000	1.21
+++ includes/form.inc	28 Nov 2005 15:16:56 -0000
@@ -161,7 +161,7 @@
     }
   }
 
-  /* Validate the current input */
+  // Validate the current input.
   if (!$elements['#validated'] && $elements['#input']) {
     // An empty checkbox returns 0, an empty textfield returns '' so we use empty().
     // Unfortunately, empty('0') returns TRUE so we need a special check for the '0' string.
@@ -169,18 +169,11 @@
       form_error($elements, t('%name field is required', array('%name' => $elements['#title'])));
     }
     if (isset($elements['#validate'])) {
-      if (is_array($elements['#validate'])) {
-        foreach ($elements['#validate'] as $key => $validate) {
-          $args = is_array($elements['#validate_arguments'][$key]) ? $elements['#validate_arguments'][$key] : array();
-          if (function_exists($validate))  {
-            call_user_func_array($validate, array_merge(array($elements), $args));
-          }
-        }
-      }
-      else {
-        $args = is_array($elements['#validate_arguments']) ? $elements['#validate_arguments'] : array();
-        if (function_exists($elements['#validate']))  {
-          call_user_func_array($elements['#validate'], array_merge(array($elements), $args));
+      $checks = _form_parse_callbacks($elements['#validate']);
+      foreach ($checks as $func => $args) {
+        $args = array_merge(array($elements), $args);
+        if ($msg = call_user_func_array($func, $args)) {
+          form_error($elements, $msg);
         }
       }
     }
@@ -189,6 +182,67 @@
 }
 
 /**
+ * Get function names and arguments.
+ *
+ * @param mixed $callbacks
+ *   May be any of:
+ *
+ *   1) Array, multiple arguments for each function:
+ *
+ *     'function1' => array(arg1, arg2, ...), // may be mixed with (2)
+ *     'function2' => array(arg1, arg2, ...),
+ *     ...
+ *
+ *   2) Array, single argument for each function:
+ *
+ *     'function1' => arg,                    // may be mixed with (1)
+ *     'function2' => arg,
+ *     ...
+ *
+ *   3) Array, no arguments for any function:
+ *
+ *     'function1', 'function2', ...          // numeric keys
+ *     ...
+ *
+ *   4) String naming a valid function.
+ *
+ * @return array
+ *   All callbacks in format (1) above.
+ */
+function _form_parse_callbacks($callbacks) {
+  $funcs = array();
+
+  // Callbacks array: many funcs.
+  if (is_array($callbacks)) {
+    foreach ($callbacks as $func=>$args) {
+
+      // Numeric key: func with no args.
+      if (is_numeric($func)) {
+        $func = $args;
+        $args = array();
+      }
+
+      // Non-array for args: single arg.
+      else if (!is_array($args)) {
+        $args = array($args);
+      }
+
+      // Make sure func exists.
+      if (function_exists($func)) {
+        $funcs[$func] = $args;
+      }
+    }
+  }
+
+  // Callback string: a single func.
+  else if (function_exists($callbacks)) {
+    $funcs[$callbacks] = array();
+  }
+
+  return $funcs;
+}
+
+/**
  * File an error against a form element. If the name of the element is
  * edit[foo][bar] then you may pass either foo or foo][bar as $name
  * foo will set an error for all its children.
