I am writing a parameter parser for a bash-like shell that I am developing.
However, in order to be compatible with bash parameters, I have to read some parameters starting with "+", for example:
./42sh +O autocd [...]
(The manual page says that these parameters are passed inline shopt, which sets the parameter values).
The problem is that the function getopt_long()only returns parameters starting with -or --if they are not alone. If they are, bash advises them accordingly as an alias for standard input and an option marker.
How do I get this type of parameters with getopt_long()? Should I make out these options myself?
EDIT: according to @jxh's answer and the page, man 3 getoptI found that getoptit getopt_longorganizes an array of parameters **argvto move all the arguments that do not seem valid - from their point of view - at the end. So, I wrote the following code after the regular code, which receives the usual parameters (all suggestions and comments are very appreciated):
EDIT2: fixed memory leak due to strdup () on each iteration of the loop.
for(; optind < argc; ++optind)
{
const char *argv_copy = strdup(argv[optind]);
if (argv_copy[0] == '+' && argv_copy[1] == 'O')
{
if (handle_shopt_options(shell_options,
argv[optind + 1],
DISABLE) == EXIT_FAILURE)
{
usage(argv[optind]);
free_shell_options(shell_options);
shell_options = NULL;
}
++optind;
}
free(argv_copy);
argv_copy = NULL;
}
Some explanations:
optind- This is an index argvthat tells us which argument will be analyzed in the next pass. Since we have analyzed all valid arguments for getopt () points of view, and since getopt () moves all non-options at the end, we will analyze all other arguments, including those that interest us.argv[argc] == NULL: , , , , optind == argc.argv, , , , , .
:
getopt_long() , _GNU_SOURCE.strdup() _XOPEN_SOURCE >= 500 _POSIX_C_SOURCE >= 200809L.