Created
June 26, 2019 13:23
-
-
Save RChehowski/9938ee014806e001229830afacfd9de9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PRIVATE_FUNCTION int32 _convert_cli_options(const char* program_arguments, JNIEnv* env, jobjectArray* OUT_program_arguments_array) | |
{ | |
NULL_CHECK(env); | |
NULL_CHECK(OUT_program_arguments_array); | |
const char* const non_null_program_arguments = EITHER(program_arguments, ""); | |
// Error message will be empty if succeeded | |
char err_msg[4096]; | |
const size_t err_msg_length = LENGTH_OF_STATIC_ARRAY(err_msg); | |
memset(&err_msg, 0, err_msg_length * sizeof(char)); | |
// Allocate java objects | |
jclass string_class = NULL; | |
jstring check_regex_string = NULL; | |
jstring program_arguments_string = NULL; | |
jstring split_regex_string = NULL; | |
jmethodID matches_method_id = NULL; | |
jmethodID split_method_id = NULL; | |
jobjectArray arguments_array = NULL; | |
// !!! Each line of this code retrieves a single java lang item, one should read it sequentially !!! | |
string_class = (*env)->FindClass(env, STRING_CLASS_NAME); | |
if (!string_class) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable to find class: \"%s\"", | |
MACRO_STR(string_class), STRING_CLASS_NAME); | |
goto exit; | |
} | |
check_regex_string = (*env)->NewStringUTF(env, STRING_IS_SPACES_REGEX); | |
if (!check_regex_string) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable to allocate string: \"%s\"", | |
MACRO_STR(check_regex_string), STRING_IS_SPACES_REGEX); | |
goto exit; | |
} | |
program_arguments_string = (*env)->NewStringUTF(env, non_null_program_arguments); | |
if (!program_arguments_string) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable to allocate string: \"%s\"", | |
MACRO_STR(program_arguments_string), non_null_program_arguments); | |
goto exit; | |
} | |
matches_method_id = (*env)->GetMethodID(env, string_class, STRING_MATCHES_METHOD_NAME, "(L"STRING_CLASS_NAME";)Z"); | |
if (!matches_method_id) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable find method \"%s\" in \"%s\"", | |
MACRO_STR(matches_method_id), STRING_MATCHES_METHOD_NAME, STRING_CLASS_NAME); | |
goto exit; | |
} | |
// Check whether the string contains spaces only | |
const jboolean string_is_empty = (*env)->CallBooleanMethod(env, program_arguments_string, matches_method_id, check_regex_string); | |
if (!string_is_empty) | |
{ | |
// Wasn't empty. So split it. | |
split_regex_string = (*env)->NewStringUTF(env, STRING_SPLIT_REGEX); | |
if (!split_regex_string) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable to allocate string: \"%s\"", | |
MACRO_STR(split_regex_string), STRING_SPLIT_REGEX); | |
goto exit; | |
} | |
split_method_id = (*env)->GetMethodID(env, string_class, STRING_SPLIT_METHOD_NAME, "(L"STRING_CLASS_NAME";)[L"STRING_CLASS_NAME";"); | |
if (!split_method_id) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" in null; unable find method \"%s\" in \"%s\"", | |
MACRO_STR(split_method_id), STRING_SPLIT_METHOD_NAME, STRING_CLASS_NAME); | |
goto exit; | |
} | |
arguments_array = (*env)->CallObjectMethod(env, program_arguments_string, split_method_id, split_regex_string); | |
if (!arguments_array) | |
{ | |
snprintf(err_msg, err_msg_length, "\"%s\" method, called on \"%s\" returned NULL; unexpected result", | |
STRING_SPLIT_METHOD_NAME, non_null_program_arguments); | |
goto exit; | |
} | |
} | |
else | |
{ | |
// Was empty or contained space(s) only. Create an empty string array. | |
arguments_array = (*env)->NewObjectArray(env, 0, string_class, NULL); | |
if (!arguments_array) | |
{ | |
snprintf(err_msg, err_msg_length, "Unable to allocate \"%s\" of 0 length, bad alloc", MACRO_STR(arguments_array)); | |
goto exit; | |
} | |
} | |
exit: | |
if (string_class) (*env)->DeleteLocalRef(env, string_class); | |
if (check_regex_string) (*env)->DeleteLocalRef(env, check_regex_string); | |
if (program_arguments_string) (*env)->DeleteLocalRef(env, program_arguments_string); | |
if (split_regex_string) (*env)->DeleteLocalRef(env, split_regex_string); | |
if (matches_method_id) (*env)->DeleteLocalRef(env, matches_method_id); | |
if (split_method_id) (*env)->DeleteLocalRef(env, split_method_id); | |
if (arguments_array) (*env)->DeleteLocalRef(env, arguments_array); | |
*OUT_program_arguments_array = arguments_array; | |
return RESULT_OK; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment