Skip to content

Instantly share code, notes, and snippets.

@RChehowski
Created June 26, 2019 13:23
Show Gist options
  • Save RChehowski/9938ee014806e001229830afacfd9de9 to your computer and use it in GitHub Desktop.
Save RChehowski/9938ee014806e001229830afacfd9de9 to your computer and use it in GitHub Desktop.
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