=== modified file 'includes/registry.inc'
--- includes/registry.inc	2009-05-16 16:04:42 +0000
+++ includes/registry.inc	2009-05-17 23:31:38 +0000
@@ -45,11 +45,13 @@ function _registry_rebuild() {
   system_get_files_database($modules, 'module');
   // Get the list of files we are going to parse.
   $files = array();
+  $module_list = array();
   foreach ($modules as $module) {
     if ($module->status) {
       // Parse .info file only for enabled modules.
       $module->info = drupal_parse_info_file(dirname($module->filepath) . '/' . $module->name . '.info');
       $dir = dirname($module->filepath);
+      $module_list[] = $module->name;
       foreach ($module->info['files'] as $file) {
         $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
       }
@@ -75,7 +77,11 @@ function _registry_rebuild() {
         ->execute();
     }
   }
-  $parsed_files = _registry_parse_files($files);
+  // We want the longer modules match first to prevent function name clashes
+  // between modules sharing the same prefix.
+  rsort($module_list);
+  $module_preg = '/^(' . implode('|', $module_list) . ')_(.*)$/';
+  $parsed_files = _registry_parse_files($files, $module_preg);
 
   $unchanged_resources = array();
   $lookup_cache = array();
@@ -116,8 +122,11 @@ function registry_get_parsed_files() {
  *
  * @param $files
  *  The list of files to check and parse.
+ * @param $module_preg
+ *   A regular expression containing the list of enabled modules, prepared for
+ *   hook matching.
  */
-function _registry_parse_files($files) {
+function _registry_parse_files($files, $module_preg) {
   $parsed_files = array();
   foreach ($files as $filename => $file) {
     $contents = file_get_contents($filename);
@@ -127,7 +136,7 @@ function _registry_parse_files($files) {
       $parsed_files[] = $filename;
       // We update the md5 after we've saved the files resources rather than here, so if we
       // don't make it through this rebuild, the next run will reparse the file.
-      _registry_parse_file($filename, $contents, $file['module'], $file['weight']);
+      _registry_parse_file($filename, $contents, $module_preg, $file['weight']);
       $file['md5'] = $md5;
       db_merge('registry_file')
         ->key(array('filename' => $filename))
@@ -145,12 +154,13 @@ function _registry_parse_files($files) {
  *  Name of the file we are going to parse.
  * @param $contents
  *  Contents of the file we are going to parse as a string.
- * @param $module
- *   (optional) Name of the module this file belongs to.
+ * @param $module_preg
+ *   A regular expression containing the list of enabled modules, prepared for
+ *   hook matching.
  * @param $weight
  *   (optional) Weight of the module.
  */
-function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
+function _registry_parse_file($filename, $contents, $module_preg, $weight = 0) {
   $map = &drupal_static(__FUNCTION__, array(T_FUNCTION => 'function', T_CLASS => 'class', T_INTERFACE => 'interface'));
   // Delete registry entries for this file, so we can insert the new resources.
   db_delete('registry')
@@ -162,21 +172,18 @@ function _registry_parse_file($filename,
     if (is_array($token) && isset($map[$token[0]])) {
       $type = $map[$token[0]];
       if ($resource_name = _registry_get_resource_name($tokens, $type)) {
-        $suffix = '';
-        // Collect the part of the function name after the module name,
-        // so that we can query the registry for possible hook implementations.
-        if ($type == 'function' && !empty($module)) {
-          $n = strlen($module);
-          if (substr($resource_name, 0, $n) == $module) {
-            $suffix = substr($resource_name, $n + 1);
-          }
-        }
         $fields = array(
           'filename' => $filename,
-          'module' => $module,
-          'suffix' => $suffix,
+          'module' => '',
+          'suffix' => '',
           'weight' => $weight,
         );
+        // Collect the part of the function name after the module name,
+        // so that we can query the registry for possible hook implementations.
+        if ($type == 'function' && preg_match($module_preg, $resource_name, $matches)) {
+          $fields['module'] = $matches[1];
+          $fields['suffix'] = $matches[2];
+        }
         // Because some systems, such as cache, currently use duplicate function
         // names in separate files an insert query cannot be used here as it
         // would cause a key constraint violation. Instead we use a merge query.

=== modified file 'modules/simpletest/tests/registry.test'
--- modules/simpletest/tests/registry.test	2009-05-16 16:04:42 +0000
+++ modules/simpletest/tests/registry.test	2009-05-17 21:54:55 +0000
@@ -16,13 +16,14 @@ class RegistryParseFileTestCase extends 
     $this->className = 'registry_test_class' . md5(rand());
     $this->interfaceName = 'registry_test_interface' . md5(rand());
     parent::setUp();
+    $this->module_preg = '/^(' . implode('|', module_list()) . ')_(.*)$/';
   }
 
   /**
    * testRegistryParseFile
    */
   function testRegistryParseFile() {
-    _registry_parse_file($this->fileName, $this->getFileContents());
+    _registry_parse_file($this->fileName, $this->getFileContents(), $this->module_preg);
     foreach (array('functionName', 'className', 'interfaceName') as $resource) {
       $foundName = db_result(db_query("SELECT name FROM {registry} WHERE name = '%s'", $this->$resource));
       $this->assertTrue($this->$resource == $foundName, t('Resource "@resource" found.', array('@resource' => $this->$resource)));
@@ -83,13 +84,14 @@ class RegistryParseFilesTestCase extends
         }
       }
     }
+    $this->module_preg = '/^(' . implode('|', module_list()) . ')_(.*)$/';
   }
 
   /**
    * testRegistryParseFiles
    */
   function testRegistryParseFiles() {
-    _registry_parse_files($this->getFiles());
+    _registry_parse_files($this->getFiles(), $this->module_preg);
     foreach ($this->fileTypes as $fileType) {
       // Test that we have all the right resources.
       foreach (array('functionName', 'className', 'interfaceName') as $resource) {

