Rework arguments handle

This commit is contained in:
Yorick Barbanneau 2021-09-15 22:53:56 +02:00
parent e6c14f6bff
commit 49a797a179

View file

@ -6,6 +6,11 @@
#include <string.h> #include <string.h>
#include "utictactoe.h" #include "utictactoe.h"
#define OPTIONAL_ARGUMENT_IS_PRESENT \
((optarg == NULL && optind < argc && argv[optind][0] != '-') \
? (bool) (optarg = argv[optind++]) \
: (optarg != NULL))
void help(){ void help(){
printf("usage: utictactoe ([-i LEVEL|-x N|-o N|-v|-V|-h] | -c FILE)\n"); printf("usage: utictactoe ([-i LEVEL|-x N|-o N|-v|-V|-h] | -c FILE)\n");
printf("Play a utictactoe game with human or program players.\n"); printf("Play a utictactoe game with human or program players.\n");
@ -18,45 +23,82 @@ void help(){
printf("-h, --help display this help and exit\n"); printf("-h, --help display this help and exit\n");
printf("Tactics list: random (0), clever (1)\n"); printf("Tactics list: random (0), clever (1)\n");
} }
int check_int_value ( char *value, int min, int max){
char * end_ptr;
int result;
result = strtol(optarg, &end_ptr, 10);
if ( strcmp(end_ptr, "\0") != 0 ) {
return -1;
}
if ( result < min || result > max) {
return -1;
}
return result;
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
int optc; int optc;
int cross_ai, round_ai = 0;
int inception_level = 0; int inception_level = 0;
bool contest, round_ai, cross_ai = false; bool contest = false;
char * end_ptr;
static struct option long_opts[] = static struct option long_opts[] =
{ {
{"inception-level", optional_argument, 0, 'i'}, {"inception-level", optional_argument, 0, 'i'},
{"cross-ai", no_argument, 0, 'x'}, {"cross-ai", required_argument, 0, 'x'},
{"round-ai", no_argument, 0, 'o'}, {"round-ai", required_argument, 0, 'o'},
{"contest", no_argument, 0, 'c'}, {"contest", no_argument, 0, 'c'},
{"verbose", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'}, {"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((optc = getopt_long (argc, argv, "i:xocvVh", long_opts, NULL)) != -1){
while ((optc = getopt_long (argc, argv, "i::x:o:cvVh", long_opts, NULL)) != -1){
switch (optc) { switch (optc) {
case 'i': /* 'a' option */ case 'i': /* 'a' option */
printf ("Inception activated\n"); if ( OPTIONAL_ARGUMENT_IS_PRESENT ) {
if ( optarg ) { inception_level = check_int_value( optarg, 1, 3);
inception_level = strtol(optarg, &end_ptr, 10); if ( inception_level == -1 ) {
assert ( strcmp(end_ptr,"\0") == 0); fprintf(stderr, "Error: incorrect inception level\n");
assert ( inception_level >= 1 ); exit (EXIT_FAILURE);
assert ( inception_level <= 3 ); }
} }
else { else {
inception_level = 2; inception_level = 2;
} }
printf ("Inception activated, level: %d\n", inception_level);
break; break;
case 'x': case 'x':
printf ("cross ai\n"); printf ("cross ai\n");
cross_ai = true; if ( optarg ) {
cross_ai = check_int_value(optarg, 0, 1);
if ( cross_ai == -1 ) {
fprintf(stderr, "Error: incorrect cross ai value\n");
exit (EXIT_FAILURE);
}
}
else {
fprintf(stderr, "Error: you must specify a value for cross ai\n");
exit (EXIT_FAILURE);
}
break; break;
case 'o': case 'o':
printf ("round ai\n"); printf ("round ai\n");
round_ai = true; if ( optarg ) {
round_ai = check_int_value(optarg, 0, 1);
if ( round_ai == -1 ) {
fprintf(stderr, "Error: incorrect round ai value\n");
exit (EXIT_FAILURE);
}
}
else {
fprintf(stderr, "Error: you must specify a value for round ai\n");
exit (EXIT_FAILURE);
}
break; break;
case 'c': case 'c':
@ -72,6 +114,7 @@ int main(int argc, char* argv[]) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
default: default:
fprintf(stderr, "Error: unknown option");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }