makes the SDL_main code shorter
Also added a generic SDL_RunApp() implementation for platforms that
don't really need it.
Some platforms (that use SDL_main but haven't been ported yet) are
still missing, but are added in the following commits.
(remaining platforms will follow)
SDL_main.h is *not* included by SDL.h anymore, users are supposed to
include it directly now, usually only in the file they implement main() in.
If they need the header elsewhere or don't want SDL_main to implement
main() (but only call SDL_SetMainReady() or whatever), they
can #define SDL_MAIN_HANDLED first, same as before.
For SDL-internal usage, I added _SDL_MAIN_NOIMPL, which *also* skips the
implementation and `#define main SDL_main`, but still defines
SDL_MAIN_AVAILABLE and SDL_MAIN_NEEDED in SDL_main.h, as before.
To make the implementaion in the header shorter and avoid including windows.h,
I moved most of the Win32 SDL_main code into SDL3.dll via SDL_Win32RunApp(),
so the header-only part is just the different main functions calling
SDL_Win32RunApp(SDL_main, NULL)
Note that I changed changed the return value and type of OutOfMemory()
to return -1 instead of FALSE, so main() (or WinMain() or whatever)
returns -1 instead of 0 in case of an out-of-memory error
Compared to original Win32 SDL_main, I tweaked the part of the
implementation in SDL_main_impl.h a bit to avoid linker warnings
and conflicts with stuff from windows.h:
- replaced windows.h with own define of WINAPI
and typedef-ing HINSTANCE and LPSTR.
This prevents conflicts between all the generically-named #defines and
types in windows.h and user code (like DrawState in some SDL tests)
- only using one of main() or wmain() gets rid of a MSVC linker error
("warning LNK4067: ambiguous entry point")
If this still causes problems, we might try getting rid of wmain(),
seemed to me like MSVC can use regular main() in UNICODE mode as well
- simplified the UNICODE logic for that - while this is not exactly
equivalent to the old, it should make sense and Works For Me
I updated .clang-format and ran clang-format 14 over the src and test directories to standardize the code base.
In general I let clang-format have it's way, and added markup to prevent formatting of code that would break or be completely unreadable if formatted.
The script I ran for the src directory is added as build-scripts/clang-format-src.sh
This fixes:
#6592#6593#6594
* Add braces after if conditions
* More add braces after if conditions
* Add braces after while() conditions
* Fix compilation because of macro being modified
* Add braces to for loop
* Add braces after if/goto
* Move comments up
* Remove extra () in the 'return ...;' statements
* More remove extra () in the 'return ...;' statements
* More remove extra () in the 'return ...;' statements after merge
* Fix inconsistent patterns are xxx == NULL vs !xxx
* More "{}" for "if() break;" and "if() continue;"
* More "{}" after if() short statement
* More "{}" after "if () return;" statement
* More fix inconsistent patterns are xxx == NULL vs !xxx
* Revert some modificaion on SDL_RLEaccel.c
* SDL_RLEaccel: no short statement
* Cleanup 'if' where the bracket is in a new line
* Cleanup 'while' where the bracket is in a new line
* Cleanup 'for' where the bracket is in a new line
* Cleanup 'else' where the bracket is in a new line
I ran this script in the include directory:
```sh
sed -i '' -e 's,#include "\(SDL.*\)",#include <SDL3/\1>,' *.h
```
I ran this script in the src directory:
```sh
for i in ../include/SDL3/SDL*.h
do hdr=$(basename $i)
if [ x"$(echo $hdr | egrep 'SDL_main|SDL_name|SDL_test|SDL_syswm|SDL_opengl|SDL_egl|SDL_vulkan')" != x ]; then
find . -type f -exec sed -i '' -e 's,#include "\('$hdr'\)",#include <SDL3/\1>,' {} \;
else
find . -type f -exec sed -i '' -e '/#include "'$hdr'"/d' {} \;
fi
done
```
Fixes https://github.com/libsdl-org/SDL/issues/6575
If a developer uses SDL_SetMemoryFunctions, we can't rely on SDL_free()
working when SDL_main() returns.
Signed-off-by: Steven Noonan <steven@valvesoftware.com>
Signed-off-by: Sam Lantinga <slouken@libsdl.org>
Galadrim
As I have seen, SDL implements its own command line parser for Windows in SDL_windows_main.c. Unfortunately, it doesn't seem to allow command line arguments with trailing backslashes if quoting is required.
Usually, when you write an application that gets command line arguments passed as argc and argv, the parsing is done by parse_cmdline. The Windows API also provides the function CommandLineToArgvW, so an application can parse itself if only the command line string is provided. Both functions behave almost identically according to their documentation. If the argument "\\" (including the quotes) is passed, they both turn it into a single backslash.
The SDL command line parser on the other hand doesn't recognize the second quote character as the closing character in this example and therefore includes it in the parsed argument. The parser does not count the number of backslashes preceding a quote. It always treats a quote as escaped if a backslash is in front of it. Therefore, it should be impossible to quote and escape an argument correctly, if it has a trailing backslash and contains characters that require quoting.
Of course, each application is allowed to implement its own parsing rules, so SDL is free to do so. But the problem I see is that there are arguments, that are impossible to be passed to the parser correctly, as I described above. Is there a reason, why SDL does not simply use CommandLineToArgvW instead of implementing its own parser?
Here are some links that show that correct argument parsing, as it is usually done in Windows, is quite complicated:
https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvwhttp://www.windowsinspired.com/how-a-windows-programs-splits-its-command-line-into-individual-arguments/
Otherwise, we are using the allocator before the app can set up its own hooks.
Now we use VirtualAlloc, and WideCharToMultiByte (because SDL_iconv uses
SDL_malloc, too!) to get ready to call into SDL_main.
This also makes console_wmain() call into the same routines as everything
else, so we don't have to deal with those allocations, too. Hopefully we
end up with the same results from GetCommandLine() as we do in wargv.
Fixes Bugzilla #4340.
Simon Hug
There are currently three entry points in the SDL2_main code for windows: main, wmain and WinMain. Only the latter two properly convert the arguments to UTF-8.
Console applications linked with MSVC will always link with the main entry point (wmain has to be selected by manually setting the entry point). This makes it likely that such programs will not have proper unicode arguments.
Simon Hug
The SDLmain file src/main/windows/SDL_windows_main.c defines both entry points for console applications, main and wmain. This seems to confuse MSVC. It outputs a LNK4067 warning and then chooses main, which is a shame because only wmain has the unicode handling. Using SDLmain.lib provided on libsdl.org, the linker also goes for main.
I'm proposing to not define the main entry point at all. wmain should be supported well enough with MSVC.
Simon Hug
The function console_wmain in src/main/windows/SDL_windows_main.c does not null terminate the argument list it is creating. As specified by the C standard, "argv[argc] shall be a null pointer."
The SDLTest framework makes use of that null pointer and some test programs can cause an access violation because it's missing.
The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().