Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.197
diff -u -p -r1.197 module.inc
--- includes/module.inc	28 Jul 2010 01:46:59 -0000	1.197
+++ includes/module.inc	20 Aug 2010 13:27:20 -0000
@@ -72,7 +72,12 @@ function module_list($refresh = FALSE, $
         $list = system_list('bootstrap');
       }
       else {
-        $list = system_list('module_enabled');
+        $list = array();
+        foreach (system_list('module') as $name => $item) {
+          if ($item->status) {
+            $list[$name] = $name;
+          }
+        }
       }
     }
   }
@@ -91,14 +96,14 @@ function module_list($refresh = FALSE, $
  *
  * @param $type
  *   The type of list to return:
- *   - module_enabled: All enabled modules.
+ *   - module: All modules.
  *   - bootstrap: All enabled modules required for bootstrap.
  *   - theme: All themes.
  *
  * @return
  *   An associative array of modules or themes, keyed by name, and having the
- *   respective database row as value. For $type 'module_enabled' and
- *   'bootstrap', the array values equal the keys.
+ *   respective database row as value. For $type 'bootstrap', the array values
+ *   equal the keys.
  *
  * @see module_list()
  * @see list_themes()
@@ -128,13 +133,13 @@ function system_list($type) {
     $lists['bootstrap'] = array_keys($bootstrap_list);
   }
   // Otherwise build the list for enabled modules and themes.
-  elseif (!isset($lists['module_enabled'])) {
+  elseif (!isset($lists[$type])) {
     if ($cached = cache_get('system_list', 'cache_bootstrap')) {
       $lists = $cached->data;
     }
     else {
       $lists = array(
-        'module_enabled' => array(),
+        'module' => array(),
         'theme' => array(),
         'filepaths' => array(),
       );
@@ -145,9 +150,9 @@ function system_list($type) {
       // consistent with the one used in module_implements().
       $result = db_query("SELECT * FROM {system} ORDER BY weight ASC, name ASC");
       foreach ($result as $record) {
-        if ($record->type == 'module' && $record->status) {
-          // Build a list of all enabled modules.
-          $lists['module_enabled'][$record->name] = $record->name;
+        // Build a list of modules.
+        if ($record->type == 'module') {
+          $lists['module'][$record->name] = $record;
         }
         // Build a list of themes.
         if ($record->type == 'theme') {
@@ -181,6 +186,69 @@ 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', array('required'), TRUE);
+ *
+ *   // List all modules that require Taxonomy module.
+ *   system_list_by_info('module', array('dependencies'), 'taxonomy');
+ * @endcode
+ *
+ * @param $type
+ *   The type of system object to list, either 'module' or 'theme'.
+ * @param $property
+ *   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 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, $simple = TRUE) {
+  $list = array();
+  foreach (system_get_info($type, FALSE) 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 (in_array($value, $info_value)) {
+        $list[$name] = ($simple ? $info['name'] : $info);
+      }
+    }
+    // Otherwise, look whether $info_value matches $value.
+    elseif ($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
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.955
diff -u -p -r1.955 system.module
--- modules/system/system.module	20 Aug 2010 01:42:52 -0000	1.955
+++ modules/system/system.module	20 Aug 2010 13:04:55 -0000
@@ -2217,25 +2217,40 @@ function system_update_files_database(&$
 }
 
 /**
- * Returns an array of information about active modules or themes.
+ * Returns information about modules or themes.
  *
  * This function returns the information from the {system} table corresponding
  * to the cached contents of the .info file for each active module or theme.
  *
  * @param $type
- *   Either 'module' or 'theme'.
+ *   The type of system list to use:
+ *   - module: All modules.
+ *   - theme: All themes.
+ * @param $only_enabled
+ *   (optional) Boolean whether to return only enabled records for the provided
+ *   $type. Defaults to TRUE.
+ * @param $name
+ *   (optional) The name of a module or theme whose information shall be
+ *   returned. If omitted, all records for the provided $type will be returned.
+ *   If $name does not exist in the provided $type, FALSE will be returned.
  *
  * @return
- *   An associative array of module or theme information keyed by name.
+ *   An associative array of module or theme information keyed by name, or only
+ *   information for $name, if given.
  *
  * @see system_rebuild_module_data()
  * @see system_rebuild_theme_data()
  */
-function system_get_info($type) {
+function system_get_info($type, $only_enabled = TRUE, $name = NULL) {
   $info = array();
-  $result = db_query('SELECT name, info FROM {system} WHERE type = :type AND status = 1', array(':type' => $type));
-  foreach ($result as $item) {
-    $info[$item->name] = unserialize($item->info);
+  $list = system_list($type);
+  foreach ($list as $shortname => $item) {
+    if (!$only_enabled || $item->status) {
+      $info[$shortname] = unserialize($item->info);
+    }
+  }
+  if (isset($name)) {
+    return isset($info[$name]) ? $info[$name] : FALSE;
   }
   return $info;
 }
