Fri Mar 29 16:09:54 CET 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / assembly.c
index 54c893e05a3cce2a791a16be0e56ee99eb20511e..3d9a59b2f3a4fa45464706c6a532e88d09db6684 100644 (file)
@@ -51,13 +51,32 @@ g_concat_dir_and_file (const char *dir, const char *file)
 }
 
 static char *
-default_assembly_name_resolver (const char *name)
+default_assembly_name_resolver (const char *base_dir, const char *name)
 {
        char *file, *path;
        
-       if (strcmp (name, "mscorlib") == 0)
+       if ((strcmp (name, "mscorlib") == 0) ||
+                       (strcmp (name, "mscorlib.dll") == 0) ||
+                       (strcmp (name, "corlib.dll") == 0) ||
+                       (strcmp (name, "corlib") == 0))
                return g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
 
+       path = g_concat_dir_and_file (base_dir, name);
+       if (g_file_test (name, G_FILE_TEST_EXISTS))
+               return path;
+
+       file = path;
+       path = g_strconcat (file, ".dll", NULL);
+       g_free (file);
+       if (g_file_test (path, G_FILE_TEST_EXISTS))
+               return path;
+       g_free (path);
+       
+       path = g_concat_dir_and_file (MONO_ASSEMBLIES, name);
+       if (g_file_test (path, G_FILE_TEST_EXISTS))
+               return path;
+       g_free (path);
+
        file = g_strconcat (name, ".dll", NULL);
        path = g_concat_dir_and_file (MONO_ASSEMBLIES, file);
        g_free (file);
@@ -85,7 +104,8 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
        MonoImage *image;
        MonoTableInfo *t;
        int i;
-       const char *basename = strrchr (filename, '/');
+       char *fullname, *base_dir;
+       const char *base_name = strrchr (filename, G_DIR_SEPARATOR);
        static MonoAssembly *corlib;
        
        g_return_val_if_fail (filename != NULL, NULL);
@@ -98,35 +118,27 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
                return ass;
        }
        
-       if (basename == NULL)
-               basename = filename;
+       if (base_name == NULL)
+               base_name = filename;
        else
-               basename++;
+               base_name++;
 
+       if (resolver == NULL)
+               resolver = default_assembly_name_resolver;
 
-       /*
-        * Temporary hack until we have a complete corlib.dll
-        */
-       if (strcmp (basename, CORLIB_NAME) == 0 || strcmp (basename, "mscorlib") == 0) {
-               char *fullname;
-               
-               if (corlib != NULL)
-                       return corlib;
-               fullname = g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
-               image = mono_image_open (fullname, status);
-               g_free (fullname);
-       } else
-               image = mono_image_open (filename, status);
+       base_dir = g_path_get_dirname (fullname);
        
+       fullname = resolver (base_dir, filename);
+       image = mono_image_open (fullname, status);
+
        if (!image){
                if (status)
                        *status = MONO_IMAGE_ERROR_ERRNO;
+               g_free (fullname);
+               g_free (base_dir);
                return NULL;
        }
 
-       if (resolver == NULL)
-               resolver = default_assembly_name_resolver;
-
        t = &image->tables [MONO_TABLE_ASSEMBLYREF];
 
        image->references = g_new0 (MonoAssembly *, t->rows + 1);
@@ -135,9 +147,10 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
         * Create assembly struct, and enter it into the assembly cache
         */
        ass = g_new (MonoAssembly, 1);
-       ass->name = g_strdup (filename);
+       ass->name = fullname;
        ass->image = image;
 
+       g_hash_table_insert (assemblies, image->name, ass);
        g_hash_table_insert (assemblies, ass->name, ass);
        
        /*
@@ -157,7 +170,7 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
                 * ie, references to mscorlib from corlib.dll are ignored 
                 * and we do not load corlib twice.
                 */
-               if (strcmp (basename, CORLIB_NAME) == 0){
+               if (strcmp (base_name, CORLIB_NAME) == 0){
                        if (corlib == NULL)
                                corlib = ass;
                        
@@ -165,7 +178,7 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
                                continue;
                }
                
-               assembly_ref = (*resolver) (name);
+               assembly_ref = (*resolver) (base_dir, name);
 
                image->references [i] = mono_assembly_open (assembly_ref, resolver, status);
 
@@ -182,12 +195,14 @@ mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
                        if (status)
                                *status = MONO_IMAGE_MISSING_ASSEMBLYREF;
                        g_free (ass);
+                       g_free (base_dir);
                        return NULL;
                }
                g_free (assembly_ref);
        }
        image->references [i] = NULL;
 
+       g_free (base_dir);
        return ass;
 }
 
@@ -215,3 +230,11 @@ mono_assembly_close (MonoAssembly *assembly)
        g_free (assembly);
 }
 
+/*
+ * Temporary hack until we get AppDomains
+ */
+GHashTable *
+mono_get_assemblies ()
+{
+       return assemblies;
+}