Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.169
diff -u -p -r1.169 module.inc
--- includes/module.inc	8 Nov 2009 19:53:19 -0000	1.169
+++ includes/module.inc	8 Nov 2009 20:17:51 -0000
@@ -117,7 +117,7 @@ function system_list($type) {
     foreach ($result as $record) {
       // Build a list of all modules.
       if ($record->type == 'module') {
-        $lists['module'][$record->name] = $record->name;
+        $lists['module'][$record->name] = $record;
         // Build a list of all enabled modules.
         if ($record->status) {
           $lists['module_enabled'][$record->name] = $record->name;
@@ -149,6 +149,73 @@ function system_list($type) {
 }
 
 /**
+ * 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. For example:
+ * @code
+ *   system_list_by_info('module', array('required'), TRUE);
+ * @endcode
+ * would list all required Drupal core modules.
+ *
+ * @code
+ *   system_list_by_info('module', array('dependencies'), 'taxonomy');
+ * @endcode
+ * would list all modules that require Taxonomy module.
+ *
+ * @param $type
+ *   The type of system object to list, either 'module' or 'theme.
+ * @param $parents
+ *   A list of .info file property keys to search $value in, for example
+ *   array('hidden').
+ * @param $value
+ *   The value to search for, for example 'TRUE'. If the last parent key defined
+ *   in $parents is an array (such as the 'dependencies' definition), then
+ *   $value is searched in the array of values defined by a module.
+ * @param $simple
+ *   (optional) Boolean whether to return human-readable module names as values
+ *   (TRUE) or fully populated module objects including .info file information
+ *   as values (FALSE). Defaults to TRUE.
+ *
+ * @return
+ *   An associative array containing the machine-readable module name as key,
+ *   and the human-readable module name as value if $simple is TRUE, or a fully
+ *   populated module object if $simple is FALSE.
+ *
+ * @see system_list()
+ */
+function system_list_by_info($type, $parents, $value, $simple = TRUE) {
+  $list = array();
+  // @todo Add a fallback to filesystem + .info file parsing if DB is unavailable?
+  $result = system_list($type);
+  foreach ($result as $name => $object) {
+    $object->info = unserialize($object->info);
+    $info = $object->info;
+    foreach ($parents as $parent) {
+      // If the (next) parent is not found, skip to the next module.
+      if (!isset($info[$parent])) {
+        continue 2;
+      }
+      $info = $info[$parent];
+    }
+    // Check whether $info is an array first.
+    if (is_array($info)) {
+      if (in_array($value, $info)) {
+        $list[$name] = ($simple ? $object->info['name'] : $object);
+      }
+    }
+    // Otherwise, look whether $info matches $value.
+    else {
+      if ($info == $value) {
+        $list[$name] = ($simple ? $object->info['name'] : $object);
+      }
+    }
+  }
+  return $list;
+}
+
+/**
  * Find dependencies any level deep and fill in required by information too.
  *
  * @param $files
@@ -615,3 +682,4 @@ function drupal_required_modules() {
 
   return $required;
 }
+
