mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-31 22:42:52 +08:00
android: Better parsing of command line arguments.
Reference Issue #14510.
This commit is contained in:
@@ -768,9 +768,6 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env
|
|||||||
checkJNIReady();
|
checkJNIReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL main function prototype
|
|
||||||
typedef int (*SDL_main_func)(int argc, char *argv[]);
|
|
||||||
|
|
||||||
static int run_count = 0;
|
static int run_count = 0;
|
||||||
static bool allow_recreate_activity;
|
static bool allow_recreate_activity;
|
||||||
static bool allow_recreate_activity_set;
|
static bool allow_recreate_activity_set;
|
||||||
@@ -840,47 +837,61 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls,
|
|||||||
function_name = (*env)->GetStringUTFChars(env, function, NULL);
|
function_name = (*env)->GetStringUTFChars(env, function, NULL);
|
||||||
SDL_main = (SDL_main_func)dlsym(library_handle, function_name);
|
SDL_main = (SDL_main_func)dlsym(library_handle, function_name);
|
||||||
if (SDL_main) {
|
if (SDL_main) {
|
||||||
int i;
|
// Use the name "app_process" for argv[0] so PHYSFS_platformCalcBaseDir() works.
|
||||||
int argc;
|
// https://github.com/love2d/love-android/issues/24
|
||||||
int len;
|
// (note that PhysicsFS hasn't used argv on Android in a long time, but we'll keep this for compat at least for SDL3's lifetime. --ryan.)
|
||||||
char **argv;
|
const char *argv0 = "app_process";
|
||||||
bool isstack;
|
const int len = (*env)->GetArrayLength(env, array); // argv elements, not counting argv[0].
|
||||||
|
|
||||||
// Prepare the arguments.
|
size_t total_alloc_len = (SDL_strlen(argv0) + 1) + ((len + 2) * sizeof (char *)); // len+2 to allocate an array that also holds argv0 and a NULL terminator.
|
||||||
len = (*env)->GetArrayLength(env, array);
|
for (int i = 0; i < len; ++i) {
|
||||||
argv = SDL_small_alloc(char *, 1 + len + 1, &isstack); // !!! FIXME: check for NULL
|
total_alloc_len++; // null terminator.
|
||||||
argc = 0;
|
|
||||||
/* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
|
|
||||||
https://github.com/love2d/love-android/issues/24
|
|
||||||
*/
|
|
||||||
argv[argc++] = SDL_strdup("app_process");
|
|
||||||
for (i = 0; i < len; ++i) {
|
|
||||||
char *arg = NULL;
|
|
||||||
jstring string = (*env)->GetObjectArrayElement(env, array, i);
|
jstring string = (*env)->GetObjectArrayElement(env, array, i);
|
||||||
if (string) {
|
if (string) {
|
||||||
const char *utf = (*env)->GetStringUTFChars(env, string, 0);
|
const char *utf = (*env)->GetStringUTFChars(env, string, 0);
|
||||||
if (utf) {
|
if (utf) {
|
||||||
arg = SDL_strdup(utf);
|
total_alloc_len += SDL_strlen(utf) + 1;
|
||||||
(*env)->ReleaseStringUTFChars(env, string, utf);
|
(*env)->ReleaseStringUTFChars(env, string, utf);
|
||||||
}
|
}
|
||||||
(*env)->DeleteLocalRef(env, string);
|
(*env)->DeleteLocalRef(env, string);
|
||||||
}
|
}
|
||||||
if (arg == NULL) {
|
}
|
||||||
arg = SDL_strdup("");
|
|
||||||
|
void *args = malloc(total_alloc_len); // This should NOT be SDL_malloc()
|
||||||
|
if (!args) { // uhoh.
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Out of memory parsing command line!");
|
||||||
|
} else {
|
||||||
|
size_t remain = total_alloc_len - (sizeof (char *) * (len + 2));
|
||||||
|
int argc = 0;
|
||||||
|
char **argv = (char **) args;
|
||||||
|
char *ptr = (char *) &argv[len + 2];
|
||||||
|
size_t cpy = SDL_strlcpy(ptr, argv0, remain) + 1;
|
||||||
|
argv[argc++] = ptr;
|
||||||
|
SDL_assert(cpy <= remain); remain -= cpy; ptr += cpy;
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
jstring string = (*env)->GetObjectArrayElement(env, array, i);
|
||||||
|
const char *utf = string ? (*env)->GetStringUTFChars(env, string, 0) : NULL;
|
||||||
|
cpy = SDL_strlcpy(ptr, utf ? utf : "", remain) + 1;
|
||||||
|
if (cpy < remain) {
|
||||||
|
argv[argc++] = ptr;
|
||||||
|
remain -= cpy;
|
||||||
|
ptr += cpy;
|
||||||
|
}
|
||||||
|
if (utf) {
|
||||||
|
(*env)->ReleaseStringUTFChars(env, string, utf);
|
||||||
|
}
|
||||||
|
if (string) {
|
||||||
|
(*env)->DeleteLocalRef(env, string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
argv[argc++] = arg;
|
argv[argc] = NULL;
|
||||||
|
|
||||||
|
// Run the application.
|
||||||
|
status = SDL_RunApp(argc, argv, SDL_main, NULL);
|
||||||
|
|
||||||
|
// Release the arguments.
|
||||||
|
free(args); // This should NOT be SDL_free()
|
||||||
}
|
}
|
||||||
argv[argc] = NULL;
|
|
||||||
|
|
||||||
// Run the application.
|
|
||||||
status = SDL_main(argc, argv);
|
|
||||||
|
|
||||||
// Release the arguments.
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
SDL_free(argv[i]);
|
|
||||||
}
|
|
||||||
SDL_small_free(argv, isstack);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
|
__android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user