SDL-1.2: os2 loadso improvements:

From 9f8b3ddf1c0e9066c0e70d6b08409ba748337c25 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Sat, 22 Oct 2022 17:56:10 +0300
Subject: [PATCH] os2 loadso improvements:

- SDL_LoadObject: upon failure, strip the .dll extension and retry,
  but only if module name has no path.
- SDL_LoadFunction: upon failure, retry with an underscore prepended,
  e.g. for gcc-built dlls.
- General tidy-up.
---
 src/loadso/os2/SDL_sysloadso.c | 55 +++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/loadso/os2/SDL_sysloadso.c b/src/loadso/os2/SDL_sysloadso.c
index c2d991175..6830b0536 100644
--- a/src/loadso/os2/SDL_sysloadso.c
+++ b/src/loadso/os2/SDL_sysloadso.c
@@ -36,37 +36,58 @@
 void *SDL_LoadObject(const char *sofile)
 {
     HMODULE handle = NULLHANDLE;
-    char buf[512];
+    char buf[256];
     APIRET ulrc = DosLoadModule(buf, sizeof (buf), (char *) sofile, &handle);
 
+    if (ulrc != NO_ERROR && !SDL_strrchr(sofile, '\\') && !SDL_strrchr(sofile, '/')) {
+        /* strip .dll extension and retry only if name has no path. */
+        size_t len = SDL_strlen(sofile);
+        if (len > 4 && SDL_strcasecmp(&sofile[len - 4], ".dll") == 0) {
+            char *ptr = SDL_stack_alloc(char, len);
+            SDL_memcpy(ptr, sofile, len);
+            ptr[len-4] = '\0';
+            ulrc = DosLoadModule(buf, sizeof (buf), ptr, &handle);
+            SDL_stack_free(ptr);
+        }
+    }
+
     /* Generate an error message if all loads failed */
-    if ((ulrc != NO_ERROR) || (handle == NULLHANDLE))
+    if (ulrc != NO_ERROR) {
         SDL_SetError("Failed loading %s: %s", sofile, buf);
+        handle = NULLHANDLE;
+    }
 
-    return((void *) handle);
+    return (void *)handle;
 }
 
 void *SDL_LoadFunction(void *handle, const char *name)
 {
-    const char *loaderror = "Unknown error";
     PFN symbol = NULL;
-    APIRET ulrc = DosQueryProcAddr((HMODULE)handle, 0, (char *)name, &symbol);
-
-    if (ulrc == ERROR_INVALID_HANDLE)
-        loaderror = "Invalid module handle";
-    else if (ulrc == ERROR_INVALID_NAME)
-        loaderror = "Symbol not found";
-
-    if (symbol == NULL)
-        SDL_SetError("Failed loading %s: %s", name, loaderror);
-
-    return((void *) symbol);
+    APIRET ulrc = DosQueryProcAddr((HMODULE)handle, 0, name, &symbol);
+
+    if (ulrc != NO_ERROR) {
+        /* retry with an underscore prepended, e.g. for gcc-built dlls. */
+        size_t len = SDL_strlen(name) + 1;
+        char *_name = SDL_stack_alloc(char, len + 1);
+        _name[0] = '_';
+        SDL_memcpy(&_name[1], name, len);
+        ulrc = DosQueryProcAddr((HMODULE)handle, 0, _name, &symbol);
+        SDL_stack_free(_name);
+    }
+
+    if (ulrc != NO_ERROR) {
+        SDL_SetError("Failed loading procedure %s (E%u)", name, ulrc);
+        symbol = NULL;
+    }
+
+    return (void *)symbol;
 }
 
 void SDL_UnloadObject(void *handle)
 {
-    if ( handle != NULL )
-        DosFreeModule((HMODULE) handle);
+    if (handle != NULL) {
+        DosFreeModule((HMODULE)handle);
+    }
 }
 
 #endif /* SDL_LOADSO_OS2 */