[Client] Refactor argument parsing code

This commit is contained in:
Matteo Cypriani 2010-07-13 16:59:45 +02:00
parent 3e80537c73
commit e992159810
1 changed files with 221 additions and 166 deletions

View File

@ -22,8 +22,47 @@
/* Program arguments (getopt string) */
#define OPTIONS "d:i:l::n:p:t:"
/* Function headers */
void print_usage(char *prog) ;
void parse_command_line(int argc, char **argv) ;
void parse_main_options(int argc, char **argv) ;
void check_destination_ip(void) ;
void parse_calibration_data(int argc, char **argv) ;
void check_configuration(void) ;
#ifdef DEBUG
void print_configuration(void) ;
#endif // DEBUG
void print_usage(void) ;
/* Options */
struct {
char dest_ip[16] ; // Destination IP of the packets
long dest_port ;
char iface[IFNAMSIZ + 1] ; // Source network interface
long delay ; // Time between two packet transmissions
short nb_pkt ; // Number of packets to send
long listening_port ;
// Calibration data:
DIRECTION direction ;
float x ;
float y ;
float z ;
} options = {
"",
LOC_REQUEST_DEFAULT_PORT,
"",
-1,
-1,
-1,
0, 0, 0, 0
} ;
char *program_name = NULL ;
// TRUE if the packet is a calibration request, FALSE if it is a simple
// positioning request:
BOOL is_calibration_request = FALSE ;
@ -42,171 +81,11 @@ int main(int argc, char *argv[])
int i ; // Iterator
// TRUE if the packet is a calibration request, FALSE if it is a simple
// positioning request:
BOOL is_calibration_request = FALSE ;
struct {
char dest_ip[16] ; // Destination IP of the packets
long dest_port ;
char iface[IFNAMSIZ + 1] ; // Source network interface
long delay ; // Time between two packet transmissions
short nb_pkt ; // Number of packets to send
long listening_port ;
// Calibration data:
DIRECTION direction ;
float x ;
float y ;
float z ;
} options = {
"",
LOC_REQUEST_DEFAULT_PORT,
"",
-1,
-1,
-1,
0, 0, 0, 0
} ;
int opt ; // getopt return value
// Position of the mobile as computed by the infrastructure:
float x, y, z ;
/* Parse command line */
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{
switch (opt)
{
case 'd' :
strncpy(options.dest_ip, optarg, 16) ;
break ;
case 'i' :
strncpy(options.iface, optarg, IFNAMSIZ + 1) ;
break ;
case 'l' :
/* Facultative getopt options does not handle separated
* values (like -l <port>) */
if (optarg == 0)
{
/* If we are at the end of the string, or the next optind
* is an option, we have -l without a port number */
if (argv[optind] == NULL || argv[optind][0] == '-')
// Take the default value:
options.listening_port = MOBILE_DEFAULT_PORT ;
else
{
// Take the optind value:
options.listening_port = strtol(argv[optind], NULL, 0) ;
optind++ ;
}
}
else // We got an option like -l<port>, it's OK
options.listening_port = strtol(optarg, NULL, 0) ;
break ;
case 'n' :
options.nb_pkt = strtol(optarg, NULL, 0) ;
break ;
case 'p' :
options.dest_port = strtol(optarg, NULL, 0) ;
break ;
case 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
default :
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
/* Check if we got a destination IP address */
if (options.dest_ip[0] == '\0')
{
fprintf(stderr, "Error! You must specify a destination IP address"
" (-d).\n") ;
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
/* Parse remaining arguments (possible calibration data) */
if (argc - optind != 0)
{
if (argc - optind == 4)
{
is_calibration_request = TRUE ;
options.direction = strtol(argv[optind++], NULL, 0) ;
options.x = strtod(argv[optind++], NULL) ;
options.y = strtod(argv[optind++], NULL) ;
options.z = strtod(argv[optind], NULL) ;
}
else // Bad number of arguments
{
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
/* Check options and initialise uninitialised data */
// Delay not specified (or bad delay):
if (options.delay < 0)
{
#ifdef DEBUG
fprintf(stderr,
"Warning! delay: failing back to default value.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.delay = DEFAULT_DELAY_CALIB ;
else
options.delay = DEFAULT_DELAY_NORMAL ;
}
// Number of packet not specified (or bad number)
if (options.nb_pkt < 1)
{
#ifdef DEBUG
fprintf(stderr,
"Warning! nb_pkt: failing back to default value.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.nb_pkt = DEFAULT_NBPKT_CALIB ;
else
options.nb_pkt = DEFAULT_NBPKT_NORMAL ;
}
// We want to send a calibration request AND to be located, which is
// not allowed:
if (is_calibration_request && options.listening_port != -1)
{
#ifdef DEBUG
fprintf(stderr, "Warning! You cannot wait for a server answer when"
" you calibrate. Option -l ignored…\n") ;
#endif // DEBUG
options.listening_port = -1 ;
}
#ifdef DEBUG
fprintf(stderr, "Options:\n"
"\tDestination IP: %s\n"
"\tDestination port: %ld\n"
"\tInterface: %s\n"
"\tDelay: %ld\n"
"\tNumber of packets: %d\n"
"\tListening port: %ld\n"
"\tDirection: %d\n"
"\tX: %f\n"
"\tY: %f\n"
"\tZ: %f\n"
,
options.dest_ip,
options.dest_port,
options.iface,
options.delay,
options.nb_pkt,
options.listening_port,
options.direction,
options.x,
options.y,
options.z
) ;
#endif // DEBUG
program_name = argv[0] ;
parse_command_line(argc, argv) ;
/* Open UDP socket to the aggregator */
sockfd = create_udp_sending_socket(options.dest_ip, options.dest_port,
@ -325,7 +204,183 @@ int main(int argc, char *argv[])
void print_usage(char *prog)
void parse_command_line(int argc, char **argv)
{
parse_main_options(argc, argv) ;
check_destination_ip() ;
parse_calibration_data(argc, argv) ;
check_configuration() ;
#ifdef DEBUG
print_configuration() ;
#endif // DEBUG
}
void parse_main_options(int argc, char **argv)
{
int opt ;
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{
switch (opt)
{
case 'd' :
strncpy(options.dest_ip, optarg, 16) ;
break ;
case 'i' :
strncpy(options.iface, optarg, IFNAMSIZ + 1) ;
break ;
case 'l' :
/* Facultative getopt options does not handle separated
* values (like -l <port>) */
if (optarg == 0)
{
/* If we are at the end of the string, or the next optind
* is an option, we have -l without a port number */
if (argv[optind] == NULL || argv[optind][0] == '-')
// Take the default value:
options.listening_port = MOBILE_DEFAULT_PORT ;
else
{
// Take the optind value:
options.listening_port = strtol(argv[optind], NULL, 0) ;
optind++ ;
}
}
else // We got an option like -l<port>, it's OK
options.listening_port = strtol(optarg, NULL, 0) ;
break ;
case 'n' :
options.nb_pkt = strtol(optarg, NULL, 0) ;
break ;
case 'p' :
options.dest_port = strtol(optarg, NULL, 0) ;
break ;
case 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
default :
print_usage() ;
exit(ERR_BAD_USAGE) ;
}
}
}
void check_destination_ip()
{
/* Check if we got a destination IP address */
if (options.dest_ip[0] == '\0')
{
fprintf(stderr, "Error! You must specify a destination IP address"
" (-d).\n") ;
print_usage() ;
exit(ERR_BAD_USAGE) ;
}
}
void parse_calibration_data(int argc, char **argv)
{
/* Parse remaining arguments (possible calibration data) */
if (argc - optind != 0)
{
if (argc - optind == 4)
{
is_calibration_request = TRUE ;
options.direction = strtol(argv[optind++], NULL, 0) ;
options.x = strtod(argv[optind++], NULL) ;
options.y = strtod(argv[optind++], NULL) ;
options.z = strtod(argv[optind], NULL) ;
}
else // Bad number of arguments
{
print_usage() ;
exit(ERR_BAD_USAGE) ;
}
}
}
void check_configuration()
{
// Delay not specified (or bad delay):
if (options.delay < 0)
{
#ifdef DEBUG
fprintf(stderr,
"Warning! delay: failing back to default value.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.delay = DEFAULT_DELAY_CALIB ;
else
options.delay = DEFAULT_DELAY_NORMAL ;
}
// Number of packet not specified (or bad number)
if (options.nb_pkt < 1)
{
#ifdef DEBUG
fprintf(stderr,
"Warning! nb_pkt: failing back to default value.\n") ;
#endif // DEBUG
if (is_calibration_request)
options.nb_pkt = DEFAULT_NBPKT_CALIB ;
else
options.nb_pkt = DEFAULT_NBPKT_NORMAL ;
}
// We want to send a calibration request AND to be located, which is
// not allowed:
if (is_calibration_request && options.listening_port != -1)
{
#ifdef DEBUG
fprintf(stderr, "Warning! You cannot wait for a server answer when"
" you calibrate. Option -l ignored…\n") ;
#endif // DEBUG
options.listening_port = -1 ;
}
}
#ifdef DEBUG
void print_configuration()
{
fprintf(stderr, "Options:\n"
"\tDestination IP: %s\n"
"\tDestination port: %ld\n"
"\tInterface: %s\n"
"\tDelay: %ld\n"
"\tNumber of packets: %d\n"
"\tListening port: %ld\n"
"\tDirection: %d\n"
"\tX: %f\n"
"\tY: %f\n"
"\tZ: %f\n"
,
options.dest_ip,
options.dest_port,
options.iface,
options.delay,
options.nb_pkt,
options.listening_port,
options.direction,
options.x,
options.y,
options.z
) ;
}
#endif // DEBUG
void print_usage()
{
printf("Usage:\n"
"Localisation request:\n"
@ -349,8 +404,8 @@ void print_usage(char *prog)
" Optional argument 'port' allows to specify the listening"
" port (default: %d).\n"
,
prog,
prog,
program_name,
program_name,
LOC_REQUEST_DEFAULT_PORT,
MOBILE_DEFAULT_PORT
) ;