#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include "php_getopt.h"
#define OPTERRCOLON (1)
#define OPTERRNF (2)
#define OPTERRARG (3)
static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
{
if (show_err)
{
fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
switch(err)
{
case OPTERRCOLON:
fprintf(stderr, ": in flags\n");
break;
case OPTERRNF:
fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
break;
case OPTERRARG:
fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
break;
default:
fprintf(stderr, "unknown\n");
break;
}
}
return('?');
}
int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
{
static int optchr = 0;
static int dash = 0;
int arg_start = 2;
int opts_idx = -1;
if (*optind >= argc) {
return(EOF);
}
if (!dash) {
if ((argv[*optind][0] != '-')) {
return(EOF);
} else {
if (!argv[*optind][1])
{
return(EOF);
}
}
}
if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
if (argv[*optind][2] == '\0') {
(*optind)++;
return(EOF);
}
while (1) {
opts_idx++;
if (opts[opts_idx].opt_char == '-') {
(*optind)++;
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
} else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
break;
}
}
optchr = 0;
dash = 0;
arg_start = 2 + strlen(opts[opts_idx].opt_name);
} else {
if (!dash) {
dash = 1;
optchr = 1;
}
if (argv[*optind][optchr] == ':') {
dash = 0;
(*optind)++;
return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
}
arg_start = 1 + optchr;
}
if (opts_idx < 0) {
while (1) {
opts_idx++;
if (opts[opts_idx].opt_char == '-') {
int errind = *optind;
int errchr = optchr;
if (!argv[*optind][optchr+1]) {
dash = 0;
(*optind)++;
} else {
optchr++;
arg_start++;
}
return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
} else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
break;
}
}
}
if (opts[opts_idx].need_param) {
dash = 0;
if(!argv[*optind][arg_start]) {
(*optind)++;
if (*optind == argc) {
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
}
*optarg = argv[(*optind)++];
} else {
*optarg = &argv[*optind][arg_start];
(*optind)++;
}
return opts[opts_idx].opt_char;
} else {
if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
if (!argv[*optind][optchr+1])
{
dash = 0;
(*optind)++;
} else {
optchr++;
}
} else {
(*optind)++;
}
return opts[opts_idx].opt_char;
}
assert(0);
return(0);
}