Skip to content

Instantly share code, notes, and snippets.

@RChehowski
Created June 26, 2019 13:38
Show Gist options
  • Save RChehowski/99d003c6bc12a8018f9ee1f4f205f33c to your computer and use it in GitHub Desktop.
Save RChehowski/99d003c6bc12a8018f9ee1f4f205f33c to your computer and use it in GitHub Desktop.
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[1024];
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:
// Write into the output array
*OUT_program_arguments_array = arguments_array;
// Delete local references for `initialized` java objects
DELETE_LOCAL_REF_IF_NOT_NULL(env, string_class);
DELETE_LOCAL_REF_IF_NOT_NULL(env, check_regex_string);
DELETE_LOCAL_REF_IF_NOT_NULL(env, program_arguments_string);
DELETE_LOCAL_REF_IF_NOT_NULL(env, split_regex_string);
DELETE_LOCAL_REF_IF_NOT_NULL(env, matches_method_id);
DELETE_LOCAL_REF_IF_NOT_NULL(env, split_method_id);
DELETE_LOCAL_REF_IF_NOT_NULL(env, arguments_array);
// Print an error
if (strlen(err_msg) > 0)
{
RETURN_ERROR_MESSAGE(RESULT_BAD_CALL, "%s; %s is %s", err_msg, MACRO_STR(OUT_program_arguments_array),
misc_bool_to_yes_no(arguments_array != NULL));
}
return RESULT_OK;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment