Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.198
diff -u -p -r1.198 module.inc
--- includes/module.inc	3 Sep 2010 19:49:55 -0000	1.198
+++ includes/module.inc	6 Sep 2010 20:47:04 -0000
@@ -185,6 +185,73 @@ function system_list_reset() {
 }
 
 /**
+ * Return a list of modules or themes defining a certain .info file property value.
+ *
+ * This function builds a list of all modules that are currently registered,
+ * including disabled modules. It can be used to easily find all modules that
+ * define a certain .info file property.
+ *
+ * Examples:
+ * @code
+ *   // List all required Drupal core modules.
+ *   system_list_by_info('module_enabled', array('required'), TRUE);
+ *
+ *   // List all enabled modules that require Taxonomy module.
+ *   system_list_by_info('module_enabled', array('dependencies'), 'taxonomy');
+ *
+ *   // List all enabled themes that define (any) theme settings.
+ *   system_list_by_info('theme', array('settings'));
+ * @endcode
+ *
+ * @param $type
+ *   The type of system object to list, either 'module_enabled' or 'theme'.
+ * @param $property
+ *   A list of .info file property keys to search $value in, for example
+ *   array('hidden').
+ * @param $value
+ *   (optional) The value to search for, for example 'TRUE'. If the last parent
+ *   key defined in $parents is an array (e.g., 'dependencies'), then $value is
+ *   searched in the array of defined values. If no $value is given, all items
+ *   of $type are returned that declare the $property.
+ * @param $simple
+ *   (optional) Boolean whether to return human-readable system names (TRUE) or
+ *   the .info file information as values (FALSE). Defaults to TRUE.
+ *
+ * @return
+ *   An associative array containing the machine-readable name as key, and the
+ *   human-readable name as value if $simple is TRUE, or all .info file
+ *   information if $simple is FALSE.
+ *
+ * @see system_get_info()
+ * @see system_list()
+ */
+function system_list_by_info($type, array $property, $value = NULL, $simple = TRUE) {
+  $list = array();
+  foreach (system_get_info($type) as $name => $info) {
+    // Recurse into $info using the keys specified in $property.
+    $info_value = $info;
+    foreach ($property as $key) {
+      // If the sub-key is not found, skip to the next item.
+      if (!isset($info_value[$key])) {
+        continue 2;
+      }
+      $info_value = $info_value[$key];
+    }
+    // Check whether $info_value is an array first.
+    if (is_array($info_value)) {
+      if (!isset($value) || in_array($value, $info_value)) {
+        $list[$name] = ($simple ? $info['name'] : $info);
+      }
+    }
+    // Otherwise, look whether $info_value matches $value.
+    elseif (!isset($value) || $info_value == $value) {
+      $list[$name] = ($simple ? $info['name'] : $info);
+    }
+  }
+  return $list;
+}
+
+/**
  * Find dependencies any level deep and fill in required by information too.
  *
  * @param $files
