Index: src/dynext.c
===================================================================
--- src/dynext.c	(revision 9234)
+++ src/dynext.c	(working copy)
@@ -122,6 +122,45 @@
 
 /*
 
+=item C<static char *
+filestem(char * full_name)>
+
+Returns the file stem, no path and no ext of the parameter full_name. stem is a
+freshly allocated c string.
+
+=cut
+
+*/
+
+static char *
+filestem(char * full_name)
+{
+    char * stem;
+    char * path_end;
+    char * extension_loc;
+
+    /* if there's path, remove it */
+    path_end = strrchr(full_name, '/');
+    if (! path_end)
+        path_end = strrchr(full_name, '\\');
+    if (! path_end)
+        path_end = full_name;
+    else
+        path_end++;
+    /* path_end now points at the first part of full_name that isn't path */
+
+    stem = strdup(path_end);
+
+    /* remove extension if there is one */
+    extension_loc = strrchr(stem, '.');
+    if (extension_loc)
+        *extension_loc = '\0';
+    
+    return stem;
+}
+
+/*
+
 =item C<static STRING *
 get_path(Interp *interpreter, STRING *lib, void **handle, char **lib_name)>
 
@@ -135,115 +174,106 @@
 static STRING *
 get_path(Interp *interpreter, STRING *lib, void **handle, char **lib_name)
 {
-    STRING *path;
-    char *full_name, *file_name, *file_w_ext = NULL;
-    char *tmp_lib_name, *path_end, *ext_start;
-    const char *err;
+    STRING *path = NULL;
+    char *clib = NULL;
+    char *clib_mod = NULL;
+    char *clib_no_ext = NULL;
+    int i;
 
-    /* Find the pure library name, without path or extension.  */
-    file_name = string_to_cstring(interpreter, lib);
-    tmp_lib_name = file_name;
-    path_end = strrchr(tmp_lib_name, '/');
-    if (! path_end)
-        path_end = strrchr(tmp_lib_name, '\\');
-    if (path_end)
-        tmp_lib_name = path_end+1;
-    *lib_name = malloc(strlen(tmp_lib_name)+1);
-    strcpy(*lib_name, tmp_lib_name);
-    ext_start = strrchr(*lib_name, '.');
-    if (ext_start)
-        *ext_start = '\0';
+    clib = string_to_cstring(interpreter, lib);
 
-    /*
-     * first, try to add an extension to the file if it has none.
-     */
-    if (! ext_start) {
-        file_w_ext = malloc(strlen(file_name) +
+    /* swap slashes if they're backwards */
+    for (i = 0; i < strlen(clib); i++)
+#ifdef WIN32
+        if (clib[i] == '/')
+            clib[i] = '\\';
+#else
+        if (clib[i] == '\\')
+            clib[i] = '/';
+#endif
+
+    /* try to load unmodified */
+    *handle = Parrot_dlopen(clib);
+    if (*handle) {
+        path = string_from_cstring(interpreter, clib, 0);
+        *lib_name = filestem(clib);
+    }
+    if (path)
+        goto done;
+
+    /* FIXME rm: check for malloc failures and handle them the parrot way */
+    
+    /* try to add extension */
+    clib_mod = malloc(strlen(clib) + strlen(PARROT_LOAD_EXT) + 1);
+    strcpy(clib_mod, clib);
+    strcat(clib_mod, PARROT_LOAD_EXT);
+    *handle = Parrot_dlopen(clib_mod);
+    if (*handle) {
+        path = string_from_cstring(interpreter, clib, 0);
+        *lib_name = filestem(clib);
+    }
+    if (path)
+        goto done;
+
+    /* if ext, remove it (since it's apparently wrong) and put right one on */
+    string_cstring_free(clib_mod);
+    clib_mod = NULL;
+    clib_no_ext = strdup(clib);
+    char *ext_loc = strrchr(clib_no_ext, '.');
+    if (ext_loc) {
+        *ext_loc = '\0';
+        clib_mod = malloc(strlen(clib_no_ext) +
                 strlen(PARROT_LOAD_EXT) + 1);
-        strcpy(file_w_ext, file_name);
-        strcat(file_w_ext, PARROT_LOAD_EXT);
-        full_name = Parrot_locate_runtime_file(interpreter, file_w_ext,
-                PARROT_RUNTIME_FT_DYNEXT);
-        if (full_name) {
-            *handle = Parrot_dlopen(full_name);
-            if (*handle) {
-                path = string_from_cstring(interpreter, full_name, 0);
-                string_cstring_free(file_name);
-                string_cstring_free(full_name);
-                string_cstring_free(file_w_ext);
-                return path;
-            }
-            err = Parrot_dlerror();
-            fprintf(stderr, "Couldn't load '%s': %s\n",
-                    full_name, err ? err : "unknown reason");
-            string_cstring_free(file_name);
-            string_cstring_free(full_name);
-            string_cstring_free(file_w_ext);
-            return NULL;
-        }
-        /*
-         * then file.extension w/o prefix
-         */
-        *handle = Parrot_dlopen(file_w_ext);
+        strcpy(clib_mod, clib_no_ext);
+        strcat(clib_mod, PARROT_LOAD_EXT);
+        *handle = Parrot_dlopen(clib_mod);
         if (*handle) {
-            path = string_from_cstring(interpreter, file_w_ext, 0);
-            string_cstring_free(file_name);
-            string_cstring_free(file_w_ext);
-            return path;
+            path = string_from_cstring(interpreter, clib, 0);
+            *lib_name = filestem(clib);
         }
-        string_cstring_free(file_w_ext);
-        if (strcmp(PARROT_LOAD_EXT, PARROT_SHARE_EXT)) {
-            file_w_ext = malloc(strlen(file_name) +
-                    strlen(PARROT_SHARE_EXT) + 1);
-            strcpy(file_w_ext, file_name);
-            strcat(file_w_ext, PARROT_SHARE_EXT);
-            full_name = Parrot_locate_runtime_file(interpreter, file_w_ext,
-                    PARROT_RUNTIME_FT_DYNEXT);
-            if (full_name) {
-                *handle = Parrot_dlopen(full_name);
-                if (*handle) {
-                    path = string_from_cstring(interpreter, full_name, 0);
-                    string_cstring_free(file_name);
-                    string_cstring_free(file_w_ext);
-                    return path;
-                }
-                err = Parrot_dlerror();
-                fprintf(stderr, "Couldn't load '%s': %s\n",
-                        full_name, err ? err : "unknown reason");
-                string_cstring_free(file_name);
-                string_cstring_free(file_w_ext);
-                return NULL;
-            }
-            /*
-             * then file.extension w/o prefix
-             */
-            *handle = Parrot_dlopen(file_w_ext);
-            if (*handle) {
-                path = string_from_cstring(interpreter, file_w_ext, 0);
-                string_cstring_free(file_name);
-                string_cstring_free(file_w_ext);
-                return path;
-            }
-            string_cstring_free(file_w_ext);
-        }
+        if (path)
+            goto done;
     }
-    /*
-     * finally, try the given file name as is.  we still use
-     * Parrot_locate_runtime_file so that (a) relative pathnames are searched in
-     * the standard locations, and (b) the angle of the slashes are adjusted as
-     * required for non-Unix systems.
-     */
-    full_name = Parrot_locate_runtime_file(interpreter, file_name,
-                                           PARROT_RUNTIME_FT_DYNEXT);
-    if (full_name) {
-        *handle = Parrot_dlopen(full_name);
+
+    /* this doesn't work for lib's with path info or the wrong ext, but it's
+     * just duplicating old behavior. it used to be wrapped in win32 ifdef's
+     * but it doesn't hurt to try it */
+    if (memcmp(clib, "lib", 3) == 0) {
+        *handle = Parrot_dlopen(clib + 3);
         if (*handle) {
-            path = string_from_cstring(interpreter, full_name, 0);
-            string_cstring_free(file_name);
-            string_cstring_free(full_name);
-            return path;
+            path = string_from_cstring(interpreter, clib, 0);
+            *lib_name = filestem(clib);
         }
+        if (path)
+            goto done;
     }
+
+done:
+    string_cstring_free(clib);
+    string_cstring_free(clib_mod);
+    string_cstring_free(clib_no_ext);
+    return path;
+
+#if 0
+    /* try adding extension, search path and local */
+    full_name = malloc(strlen(clib) + strlen(PARROT_LOAD_EXT) + 1);
+    strcpy(full_name, clib);
+    strcat(full_name, PARROT_LOAD_EXT);
+    *handle = Parrot_dlopen(full_name);
+    if (*handle) {
+        path = string_from_cstring(interpreter, full_name, 0);
+        *lib_name = filestem(full_name);
+        string_cstring_free(full_name);
+        string_cstring_free(clib);
+        return path;
+    }
+
+    const char *err = Parrot_dlerror();
+    fprintf(stderr, "Couldn't load '%s': %s\n",
+            clib, err ? err : "unknown reason");
+    string_cstring_free(clib);
+    return NULL;
+
     /*
      * and on windows strip a leading "lib"
      * [shouldn't this happen in Parrot_locate_runtime_file instead?]
@@ -263,6 +293,7 @@
             file_name, err ? err : "unknown reason");
     string_cstring_free(file_name);
     return NULL;
+#endif
 }
 
 /*
