mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
style(kernel): tab spaces in cargs.c
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
2ce0e0ed79
commit
7b42b46942
@ -184,4 +184,4 @@ extern "C"
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,480 +33,480 @@ SOFTWARE.
|
|||||||
#define CAG_OPTION_PRINT_MIN_INDENTION 20
|
#define CAG_OPTION_PRINT_MIN_INDENTION 20
|
||||||
|
|
||||||
static void cag_option_print_value(const cag_option *option,
|
static void cag_option_print_value(const cag_option *option,
|
||||||
size_t *accessor_length, FILE *destination)
|
size_t *accessor_length, FILE *destination)
|
||||||
{
|
{
|
||||||
if (option->value_name != NULL)
|
if (option->value_name != NULL)
|
||||||
{
|
{
|
||||||
*accessor_length += fprintf(destination, "=%s", option->value_name);
|
*accessor_length += fprintf(destination, "=%s", option->value_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_print_letters(const cag_option *option, bool *first,
|
static void cag_option_print_letters(const cag_option *option, bool *first,
|
||||||
size_t *accessor_length, FILE *destination)
|
size_t *accessor_length, FILE *destination)
|
||||||
{
|
{
|
||||||
const char *access_letter;
|
const char *access_letter;
|
||||||
access_letter = option->access_letters;
|
access_letter = option->access_letters;
|
||||||
if (access_letter != NULL)
|
if (access_letter != NULL)
|
||||||
{
|
{
|
||||||
while (*access_letter)
|
while (*access_letter)
|
||||||
{
|
{
|
||||||
if (*first)
|
if (*first)
|
||||||
{
|
{
|
||||||
*accessor_length += fprintf(destination, "-%c", *access_letter);
|
*accessor_length += fprintf(destination, "-%c", *access_letter);
|
||||||
*first = false;
|
*first = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*accessor_length += fprintf(destination, ", -%c", *access_letter);
|
*accessor_length += fprintf(destination, ", -%c", *access_letter);
|
||||||
}
|
}
|
||||||
++access_letter;
|
++access_letter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_print_name(const cag_option *option, bool *first,
|
static void cag_option_print_name(const cag_option *option, bool *first,
|
||||||
size_t *accessor_length, FILE *destination)
|
size_t *accessor_length, FILE *destination)
|
||||||
{
|
{
|
||||||
if (option->access_name != NULL)
|
if (option->access_name != NULL)
|
||||||
{
|
{
|
||||||
if (*first)
|
if (*first)
|
||||||
{
|
{
|
||||||
*accessor_length += fprintf(destination, "--%s", option->access_name);
|
*accessor_length += fprintf(destination, "--%s", option->access_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*accessor_length += fprintf(destination, ", --%s", option->access_name);
|
*accessor_length += fprintf(destination, ", --%s", option->access_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t cag_option_get_print_indention(const cag_option *options,
|
static size_t cag_option_get_print_indention(const cag_option *options,
|
||||||
size_t option_count)
|
size_t option_count)
|
||||||
{
|
{
|
||||||
size_t option_index, indention, result;
|
size_t option_index, indention, result;
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
|
|
||||||
result = CAG_OPTION_PRINT_MIN_INDENTION;
|
result = CAG_OPTION_PRINT_MIN_INDENTION;
|
||||||
|
|
||||||
for (option_index = 0; option_index < option_count; ++option_index)
|
for (option_index = 0; option_index < option_count; ++option_index)
|
||||||
{
|
{
|
||||||
indention = CAG_OPTION_PRINT_DISTANCE;
|
indention = CAG_OPTION_PRINT_DISTANCE;
|
||||||
option = &options[option_index];
|
option = &options[option_index];
|
||||||
if (option->access_letters != NULL && *option->access_letters)
|
if (option->access_letters != NULL && *option->access_letters)
|
||||||
{
|
{
|
||||||
indention += strlen(option->access_letters) * 4 - 2;
|
indention += strlen(option->access_letters) * 4 - 2;
|
||||||
if (option->access_name != NULL)
|
if (option->access_name != NULL)
|
||||||
{
|
{
|
||||||
indention += strlen(option->access_name) + 4;
|
indention += strlen(option->access_name) + 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (option->access_name != NULL)
|
else if (option->access_name != NULL)
|
||||||
{
|
{
|
||||||
indention += strlen(option->access_name) + 2;
|
indention += strlen(option->access_name) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option->value_name != NULL)
|
if (option->value_name != NULL)
|
||||||
{
|
{
|
||||||
indention += strlen(option->value_name) + 1;
|
indention += strlen(option->value_name) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indention > result)
|
if (indention > result)
|
||||||
{
|
{
|
||||||
result = indention;
|
result = indention;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cag_option_print(const cag_option *options, size_t option_count,
|
void cag_option_print(const cag_option *options, size_t option_count,
|
||||||
FILE *destination)
|
FILE *destination)
|
||||||
{
|
{
|
||||||
size_t option_index, indention, i, accessor_length;
|
size_t option_index, indention, i, accessor_length;
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
bool first;
|
bool first;
|
||||||
|
|
||||||
indention = cag_option_get_print_indention(options, option_count);
|
indention = cag_option_get_print_indention(options, option_count);
|
||||||
|
|
||||||
for (option_index = 0; option_index < option_count; ++option_index)
|
for (option_index = 0; option_index < option_count; ++option_index)
|
||||||
{
|
{
|
||||||
option = &options[option_index];
|
option = &options[option_index];
|
||||||
accessor_length = 0;
|
accessor_length = 0;
|
||||||
first = true;
|
first = true;
|
||||||
|
|
||||||
fputs(" ", destination);
|
fputs(" ", destination);
|
||||||
|
|
||||||
cag_option_print_letters(option, &first, &accessor_length, destination);
|
cag_option_print_letters(option, &first, &accessor_length, destination);
|
||||||
cag_option_print_name(option, &first, &accessor_length, destination);
|
cag_option_print_name(option, &first, &accessor_length, destination);
|
||||||
cag_option_print_value(option, &accessor_length, destination);
|
cag_option_print_value(option, &accessor_length, destination);
|
||||||
|
|
||||||
for (i = accessor_length; i < indention; ++i)
|
for (i = accessor_length; i < indention; ++i)
|
||||||
{
|
{
|
||||||
fputs(" ", destination);
|
fputs(" ", destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(" ", destination);
|
fputs(" ", destination);
|
||||||
fputs(option->description, destination);
|
fputs(option->description, destination);
|
||||||
|
|
||||||
fprintf(destination, "\n");
|
fprintf(destination, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cag_option_prepare(cag_option_context *context, const cag_option *options,
|
void cag_option_prepare(cag_option_context *context, const cag_option *options,
|
||||||
size_t option_count, int argc, char **argv)
|
size_t option_count, int argc, char **argv)
|
||||||
{
|
{
|
||||||
// This just initialized the values to the beginning of all the arguments.
|
// This just initialized the values to the beginning of all the arguments.
|
||||||
context->options = options;
|
context->options = options;
|
||||||
context->option_count = option_count;
|
context->option_count = option_count;
|
||||||
context->argc = argc;
|
context->argc = argc;
|
||||||
context->argv = argv;
|
context->argv = argv;
|
||||||
context->index = 1;
|
context->index = 1;
|
||||||
context->inner_index = 0;
|
context->inner_index = 0;
|
||||||
context->forced_end = false;
|
context->forced_end = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cag_option *cag_option_find_by_name(cag_option_context *context,
|
static const cag_option *cag_option_find_by_name(cag_option_context *context,
|
||||||
char *name, size_t name_size)
|
char *name, size_t name_size)
|
||||||
{
|
{
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
// We loop over all the available options and stop as soon as we have found
|
// We loop over all the available options and stop as soon as we have found
|
||||||
// one. We don't use any hash map table, since there won't be that many
|
// one. We don't use any hash map table, since there won't be that many
|
||||||
// arguments anyway.
|
// arguments anyway.
|
||||||
for (i = 0; i < context->option_count; ++i)
|
for (i = 0; i < context->option_count; ++i)
|
||||||
{
|
{
|
||||||
option = &context->options[i];
|
option = &context->options[i];
|
||||||
|
|
||||||
// The option might not have an item name, we can just skip those.
|
// The option might not have an item name, we can just skip those.
|
||||||
if (option->access_name == NULL)
|
if (option->access_name == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to compare the name of the access name. We can use the name_size or
|
// Try to compare the name of the access name. We can use the name_size or
|
||||||
// this comparison, since we are guaranteed to have null-terminated access
|
// this comparison, since we are guaranteed to have null-terminated access
|
||||||
// names.
|
// names.
|
||||||
if (strncmp(option->access_name, name, name_size) == 0)
|
if (strncmp(option->access_name, name, name_size) == 0)
|
||||||
{
|
{
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cag_option *cag_option_find_by_letter(cag_option_context *context,
|
static const cag_option *cag_option_find_by_letter(cag_option_context *context,
|
||||||
char letter)
|
char letter)
|
||||||
{
|
{
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
// We loop over all the available options and stop as soon as we have found
|
// We loop over all the available options and stop as soon as we have found
|
||||||
// one. We don't use any look up table, since there won't be that many
|
// one. We don't use any look up table, since there won't be that many
|
||||||
// arguments anyway.
|
// arguments anyway.
|
||||||
for (i = 0; i < context->option_count; ++i)
|
for (i = 0; i < context->option_count; ++i)
|
||||||
{
|
{
|
||||||
option = &context->options[i];
|
option = &context->options[i];
|
||||||
|
|
||||||
// If this option doesn't have any access letters we will skip them.
|
// If this option doesn't have any access letters we will skip them.
|
||||||
if (option->access_letters == NULL)
|
if (option->access_letters == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify whether this option has the access letter in it's access letter
|
// Verify whether this option has the access letter in it's access letter
|
||||||
// string. If it does, then this is our option.
|
// string. If it does, then this is our option.
|
||||||
if (strchr(option->access_letters, letter) != NULL)
|
if (strchr(option->access_letters, letter) != NULL)
|
||||||
{
|
{
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_parse_value(cag_option_context *context,
|
static void cag_option_parse_value(cag_option_context *context,
|
||||||
const cag_option *option, char **c)
|
const cag_option *option, char **c)
|
||||||
{
|
{
|
||||||
// And now let's check whether this option is supposed to have a value, which
|
// And now let's check whether this option is supposed to have a value, which
|
||||||
// is the case if there is a value name set. The value can be either submitted
|
// is the case if there is a value name set. The value can be either submitted
|
||||||
// with a '=' sign or a space, which means we would have to jump over to the
|
// with a '=' sign or a space, which means we would have to jump over to the
|
||||||
// next argv index. This is somewhat ugly, but we do it to behave the same as
|
// next argv index. This is somewhat ugly, but we do it to behave the same as
|
||||||
// the other option parsers.
|
// the other option parsers.
|
||||||
if (option->value_name != NULL)
|
if (option->value_name != NULL)
|
||||||
{
|
{
|
||||||
if (**c == '=')
|
if (**c == '=')
|
||||||
{
|
{
|
||||||
context->value = ++(*c);
|
context->value = ++(*c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the next index is larger or equal to the argument count, then the
|
// If the next index is larger or equal to the argument count, then the
|
||||||
// parameter for this option is missing. The user will know about this,
|
// parameter for this option is missing. The user will know about this,
|
||||||
// since the value pointer of the context will be NULL because we don't
|
// since the value pointer of the context will be NULL because we don't
|
||||||
// set it here in that case.
|
// set it here in that case.
|
||||||
if (context->argc > context->index + 1)
|
if (context->argc > context->index + 1)
|
||||||
{
|
{
|
||||||
// We consider this argv to be the value, no matter what the contents
|
// We consider this argv to be the value, no matter what the contents
|
||||||
// are.
|
// are.
|
||||||
++context->index;
|
++context->index;
|
||||||
*c = context->argv[context->index];
|
*c = context->argv[context->index];
|
||||||
context->value = *c;
|
context->value = *c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move c to the end of the value, to not confuse the caller about our
|
// Move c to the end of the value, to not confuse the caller about our
|
||||||
// position.
|
// position.
|
||||||
while (**c)
|
while (**c)
|
||||||
{
|
{
|
||||||
++(*c);
|
++(*c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_parse_access_name(cag_option_context *context, char **c)
|
static void cag_option_parse_access_name(cag_option_context *context, char **c)
|
||||||
{
|
{
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
// Now we need to extract the access name, which is any symbol up to a '=' or
|
// Now we need to extract the access name, which is any symbol up to a '=' or
|
||||||
// a '\0'.
|
// a '\0'.
|
||||||
n = *c;
|
n = *c;
|
||||||
while (**c && **c != '=')
|
while (**c && **c != '=')
|
||||||
{
|
{
|
||||||
++*c;
|
++*c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now this will obviously always be true, but we are paranoid. Sometimes. It
|
// Now this will obviously always be true, but we are paranoid. Sometimes. It
|
||||||
// doesn't hurt to check.
|
// doesn't hurt to check.
|
||||||
assert(*c >= n);
|
assert(*c >= n);
|
||||||
|
|
||||||
// Figure out which option this name belongs to. This might return NULL if the
|
// Figure out which option this name belongs to. This might return NULL if the
|
||||||
// name is not registered, which means the user supplied an unknown option. In
|
// name is not registered, which means the user supplied an unknown option. In
|
||||||
// that case we return true to indicate that we finished with this option. We
|
// that case we return true to indicate that we finished with this option. We
|
||||||
// have to skip the value parsing since we don't know whether the user thinks
|
// have to skip the value parsing since we don't know whether the user thinks
|
||||||
// this option has one or not. Since we don't set any identifier specifically,
|
// this option has one or not. Since we don't set any identifier specifically,
|
||||||
// it will remain '?' within the context.
|
// it will remain '?' within the context.
|
||||||
option = cag_option_find_by_name(context, n, (size_t)(*c - n));
|
option = cag_option_find_by_name(context, n, (size_t)(*c - n));
|
||||||
if (option == NULL)
|
if (option == NULL)
|
||||||
{
|
{
|
||||||
// Since this option is invalid, we will move on to the next index. There is
|
// Since this option is invalid, we will move on to the next index. There is
|
||||||
// nothing we can do about this.
|
// nothing we can do about this.
|
||||||
++context->index;
|
++context->index;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We found an option and now we can specify the identifier within the
|
// We found an option and now we can specify the identifier within the
|
||||||
// context.
|
// context.
|
||||||
context->identifier = option->identifier;
|
context->identifier = option->identifier;
|
||||||
|
|
||||||
// And now we try to parse the value. This function will also check whether
|
// And now we try to parse the value. This function will also check whether
|
||||||
// this option is actually supposed to have a value.
|
// this option is actually supposed to have a value.
|
||||||
cag_option_parse_value(context, option, c);
|
cag_option_parse_value(context, option, c);
|
||||||
|
|
||||||
// And finally we move on to the next index.
|
// And finally we move on to the next index.
|
||||||
++context->index;
|
++context->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_parse_access_letter(cag_option_context *context,
|
static void cag_option_parse_access_letter(cag_option_context *context,
|
||||||
char **c)
|
char **c)
|
||||||
{
|
{
|
||||||
const cag_option *option;
|
const cag_option *option;
|
||||||
char *n = *c;
|
char *n = *c;
|
||||||
char *v;
|
char *v;
|
||||||
|
|
||||||
// Figure out which option this letter belongs to. This might return NULL if
|
// Figure out which option this letter belongs to. This might return NULL if
|
||||||
// the letter is not registered, which means the user supplied an unknown
|
// the letter is not registered, which means the user supplied an unknown
|
||||||
// option. In that case we return true to indicate that we finished with this
|
// option. In that case we return true to indicate that we finished with this
|
||||||
// option. We have to skip the value parsing since we don't know whether the
|
// option. We have to skip the value parsing since we don't know whether the
|
||||||
// user thinks this option has one or not. Since we don't set any identifier
|
// user thinks this option has one or not. Since we don't set any identifier
|
||||||
// specifically, it will remain '?' within the context.
|
// specifically, it will remain '?' within the context.
|
||||||
option = cag_option_find_by_letter(context, n[context->inner_index]);
|
option = cag_option_find_by_letter(context, n[context->inner_index]);
|
||||||
if (option == NULL)
|
if (option == NULL)
|
||||||
{
|
{
|
||||||
++context->index;
|
++context->index;
|
||||||
context->inner_index = 0;
|
context->inner_index = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We found an option and now we can specify the identifier within the
|
// We found an option and now we can specify the identifier within the
|
||||||
// context.
|
// context.
|
||||||
context->identifier = option->identifier;
|
context->identifier = option->identifier;
|
||||||
|
|
||||||
// And now we try to parse the value. This function will also check whether
|
// And now we try to parse the value. This function will also check whether
|
||||||
// this option is actually supposed to have a value.
|
// this option is actually supposed to have a value.
|
||||||
v = &n[++context->inner_index];
|
v = &n[++context->inner_index];
|
||||||
cag_option_parse_value(context, option, &v);
|
cag_option_parse_value(context, option, &v);
|
||||||
|
|
||||||
// Check whether we reached the end of this option argument.
|
// Check whether we reached the end of this option argument.
|
||||||
if (*v == '\0')
|
if (*v == '\0')
|
||||||
{
|
{
|
||||||
++context->index;
|
++context->index;
|
||||||
context->inner_index = 0;
|
context->inner_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cag_option_shift(cag_option_context *context, int start, int option,
|
static void cag_option_shift(cag_option_context *context, int start, int option,
|
||||||
int end)
|
int end)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int a_index, shift_index, shift_count, left_index, right_index;
|
int a_index, shift_index, shift_count, left_index, right_index;
|
||||||
|
|
||||||
shift_count = option - start;
|
shift_count = option - start;
|
||||||
|
|
||||||
// There is no shift is required if the start and the option have the same
|
// There is no shift is required if the start and the option have the same
|
||||||
// index.
|
// index.
|
||||||
if (shift_count == 0)
|
if (shift_count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lets loop through the option strings first, which we will move towards the
|
// Lets loop through the option strings first, which we will move towards the
|
||||||
// beginning.
|
// beginning.
|
||||||
for (a_index = option; a_index < end; ++a_index)
|
for (a_index = option; a_index < end; ++a_index)
|
||||||
{
|
{
|
||||||
// First remember the current option value, because we will have to save
|
// First remember the current option value, because we will have to save
|
||||||
// that later at the beginning.
|
// that later at the beginning.
|
||||||
tmp = context->argv[a_index];
|
tmp = context->argv[a_index];
|
||||||
|
|
||||||
// Let's loop over all option values and shift them one towards the end.
|
// Let's loop over all option values and shift them one towards the end.
|
||||||
// This will override the option value we just stored temporarily.
|
// This will override the option value we just stored temporarily.
|
||||||
for (shift_index = 0; shift_index < shift_count; ++shift_index)
|
for (shift_index = 0; shift_index < shift_count; ++shift_index)
|
||||||
{
|
{
|
||||||
left_index = a_index - shift_index;
|
left_index = a_index - shift_index;
|
||||||
right_index = a_index - shift_index - 1;
|
right_index = a_index - shift_index - 1;
|
||||||
context->argv[left_index] = context->argv[right_index];
|
context->argv[left_index] = context->argv[right_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now restore the saved option value at the beginning.
|
// Now restore the saved option value at the beginning.
|
||||||
context->argv[a_index - shift_count] = tmp;
|
context->argv[a_index - shift_count] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The new index will be before all non-option values, in such a way that they
|
// The new index will be before all non-option values, in such a way that they
|
||||||
// all will be moved again in the next fetch call.
|
// all will be moved again in the next fetch call.
|
||||||
context->index = end - shift_count;
|
context->index = end - shift_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cag_option_is_argument_string(const char *c)
|
static bool cag_option_is_argument_string(const char *c)
|
||||||
{
|
{
|
||||||
return *c == '-' && *(c + 1) != '\0';
|
return *c == '-' && *(c + 1) != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cag_option_find_next(cag_option_context *context)
|
static int cag_option_find_next(cag_option_context *context)
|
||||||
{
|
{
|
||||||
int next_index, next_option_index;
|
int next_index, next_option_index;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
// Prepare to search the next option at the next index.
|
// Prepare to search the next option at the next index.
|
||||||
next_index = context->index;
|
next_index = context->index;
|
||||||
next_option_index = next_index;
|
next_option_index = next_index;
|
||||||
|
|
||||||
// Grab a pointer to the string and verify that it is not the end. If it is
|
// Grab a pointer to the string and verify that it is not the end. If it is
|
||||||
// the end, we have to return false to indicate that we finished.
|
// the end, we have to return false to indicate that we finished.
|
||||||
c = context->argv[next_option_index];
|
c = context->argv[next_option_index];
|
||||||
if (context->forced_end || c == NULL || (uintptr_t)c == (uintptr_t)0xfffffffffffff000 /* TODO: workaround */)
|
if (context->forced_end || c == NULL || (uintptr_t)c == (uintptr_t)0xfffffffffffff000 /* TODO: workaround */)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether it is a '-'. We need to find the next option - and an option
|
// Check whether it is a '-'. We need to find the next option - and an option
|
||||||
// always starts with a '-'. If there is a string "-\0", we don't consider it
|
// always starts with a '-'. If there is a string "-\0", we don't consider it
|
||||||
// as an option neither.
|
// as an option neither.
|
||||||
while (!cag_option_is_argument_string(c))
|
while (!cag_option_is_argument_string(c))
|
||||||
{
|
{
|
||||||
c = context->argv[++next_option_index];
|
c = context->argv[++next_option_index];
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
{
|
{
|
||||||
// We reached the end and did not find any argument anymore. Let's tell
|
// We reached the end and did not find any argument anymore. Let's tell
|
||||||
// our caller that we reached the end.
|
// our caller that we reached the end.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate that we found an option which can be processed. The index of the
|
// Indicate that we found an option which can be processed. The index of the
|
||||||
// next option will be returned.
|
// next option will be returned.
|
||||||
return next_option_index;
|
return next_option_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cag_option_fetch(cag_option_context *context)
|
bool cag_option_fetch(cag_option_context *context)
|
||||||
{
|
{
|
||||||
char *c;
|
char *c;
|
||||||
int old_index, new_index;
|
int old_index, new_index;
|
||||||
|
|
||||||
// Reset our identifier to a question mark, which indicates an "unknown"
|
// Reset our identifier to a question mark, which indicates an "unknown"
|
||||||
// option. The value is set to NULL, to make sure we are not carrying the
|
// option. The value is set to NULL, to make sure we are not carrying the
|
||||||
// parameter from the previous option to this one.
|
// parameter from the previous option to this one.
|
||||||
context->identifier = '?';
|
context->identifier = '?';
|
||||||
context->value = NULL;
|
context->value = NULL;
|
||||||
|
|
||||||
// Check whether there are any options left to parse and remember the old
|
// Check whether there are any options left to parse and remember the old
|
||||||
// index as well as the new index. In the end we will move the option junk to
|
// index as well as the new index. In the end we will move the option junk to
|
||||||
// the beginning, so that non option arguments can be read.
|
// the beginning, so that non option arguments can be read.
|
||||||
old_index = context->index;
|
old_index = context->index;
|
||||||
new_index = cag_option_find_next(context);
|
new_index = cag_option_find_next(context);
|
||||||
if (new_index >= 0)
|
if (new_index >= 0)
|
||||||
{
|
{
|
||||||
context->index = new_index;
|
context->index = new_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab a pointer to the beginning of the option. At this point, the next
|
// Grab a pointer to the beginning of the option. At this point, the next
|
||||||
// character must be a '-', since if it was not the prepare function would
|
// character must be a '-', since if it was not the prepare function would
|
||||||
// have returned false. We will skip that symbol and proceed.
|
// have returned false. We will skip that symbol and proceed.
|
||||||
c = context->argv[context->index];
|
c = context->argv[context->index];
|
||||||
assert(*c == '-');
|
assert(*c == '-');
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
// Check whether this is a long option, starting with a double "--".
|
// Check whether this is a long option, starting with a double "--".
|
||||||
if (*c == '-')
|
if (*c == '-')
|
||||||
{
|
{
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
// This might be a double "--" which indicates the end of options. If this
|
// This might be a double "--" which indicates the end of options. If this
|
||||||
// is the case, we will not move to the next index. That ensures that
|
// is the case, we will not move to the next index. That ensures that
|
||||||
// another call to the fetch function will not skip the "--".
|
// another call to the fetch function will not skip the "--".
|
||||||
if (*c == '\0')
|
if (*c == '\0')
|
||||||
{
|
{
|
||||||
context->forced_end = true;
|
context->forced_end = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We parse now the access name. All information about it will be written
|
// We parse now the access name. All information about it will be written
|
||||||
// to the context.
|
// to the context.
|
||||||
cag_option_parse_access_name(context, &c);
|
cag_option_parse_access_name(context, &c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is no long option, so we can just parse an access letter.
|
// This is no long option, so we can just parse an access letter.
|
||||||
cag_option_parse_access_letter(context, &c);
|
cag_option_parse_access_letter(context, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the items so that the options come first followed by non-option
|
// Move the items so that the options come first followed by non-option
|
||||||
// arguments.
|
// arguments.
|
||||||
cag_option_shift(context, old_index, new_index, context->index);
|
cag_option_shift(context, old_index, new_index, context->index);
|
||||||
|
|
||||||
return context->forced_end == false;
|
return context->forced_end == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char cag_option_get(const cag_option_context *context)
|
char cag_option_get(const cag_option_context *context)
|
||||||
{
|
{
|
||||||
// We just return the identifier here.
|
// We just return the identifier here.
|
||||||
return context->identifier;
|
return context->identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cag_option_get_value(const cag_option_context *context)
|
const char *cag_option_get_value(const cag_option_context *context)
|
||||||
{
|
{
|
||||||
// We just return the internal value pointer of the context.
|
// We just return the internal value pointer of the context.
|
||||||
return context->value;
|
return context->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cag_option_get_index(const cag_option_context *context)
|
int cag_option_get_index(const cag_option_context *context)
|
||||||
{
|
{
|
||||||
// Either we point to a value item,
|
// Either we point to a value item,
|
||||||
return context->index;
|
return context->index;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user