Flowgrind
Advanced TCP traffic generator
fg_argparser.h File Reference

Command line argument parser. More...

#include <stdbool.h>

Go to the source code of this file.

Data Structures

struct  ap_Mutex_state
 Contains the state of all mutex. More...
 
struct  ap_Option
 Defines a valid command line option. More...
 
struct  ap_Record
 Holds a parsed command line option and its argument. More...
 
struct  arg_parser
 Internal state of the argument parser. More...
 

Enumerations

enum  ap_Has_arg { ap_no = 0, ap_yes, ap_maybe }
 Specifies whether a command line option needs an argument. More...
 

Functions

const char * ap_argument (const struct arg_parser *const ap, const int i)
 Returns the argument of a parsed option. More...
 
int ap_arguments (const struct arg_parser *const ap)
 Number of arguments parsed (may be different from argc). More...
 
bool ap_check_mutex (const struct arg_parser *const ap, const struct ap_Mutex_state *const ms, const int i, int *conflict)
 Check a new option record for mutex. More...
 
int ap_code (const struct arg_parser *const ap, const int i)
 Returns the code of a parsed option with given index. More...
 
const char * ap_error (const struct arg_parser *const ap)
 Get the string containing errors encountered during parsing. More...
 
void ap_free (struct arg_parser *const ap)
 Free internal state of arg-parser. More...
 
void ap_free_mutex_state (struct ap_Mutex_state *const ms)
 Free a mutex context. More...
 
bool ap_init (struct arg_parser *const ap, const int argc, const char *const argv[], const struct ap_Option options[], const char in_order)
 Initialize the arg-parser given command line and user-defined options. More...
 
bool ap_init_mutex_state (const struct arg_parser *const ap, struct ap_Mutex_state *const ms)
 Initialize a new mutex state table. More...
 
bool ap_is_used (const struct arg_parser *const ap, int code)
 Returns true if the option specified by code was given at least once. More...
 
const char * ap_opt_string (const struct arg_parser *const ap, const int i)
 Get the real command line option string (may be the short or long version). More...
 
const struct ap_Optionap_option (const struct arg_parser *const ap, const int i)
 Get the user-defined option for a given record position. More...
 
void ap_reset_mutex (struct ap_Mutex_state *const ms)
 Reset a mutex context. More...
 
bool ap_set_check_mutex (const struct arg_parser *const ap, struct ap_Mutex_state *const ms, const int i, int *conflict)
 Check a new option record for mutex and register it at the same time. More...
 
bool ap_set_mutex (const struct arg_parser *const ap, struct ap_Mutex_state *const ms, const int i)
 Register an option record in a mutex context. More...
 

Detailed Description

Command line argument parser.

Definition in file fg_argparser.h.

Enumeration Type Documentation

◆ ap_Has_arg

enum ap_Has_arg

Specifies whether a command line option needs an argument.

Enumerator
ap_no 

Option without argument (flag).

ap_yes 

Argument required.

ap_maybe 

Optional Argument.

Definition at line 35 of file fg_argparser.h.

35  {
37  ap_no = 0,
39  ap_yes,
41  ap_maybe
42 };

Function Documentation

◆ ap_argument()

const char* ap_argument ( const struct arg_parser *const  ap,
const int  i 
)

Returns the argument of a parsed option.

Parameters
[in]appointer to arg-parser state
[in]iindex of the parsed option
Returns
argument of parsed option at index i. If this option has code 0 (non-option), the non-option string is returned

Definition at line 478 of file fg_argparser.c.

479 {
480  if (i >= 0 && i < ap_arguments(ap))
481  return ap->data[i].argument;
482  else
483  return "";
484 }

◆ ap_arguments()

int ap_arguments ( const struct arg_parser *const  ap)

Number of arguments parsed (may be different from argc).

Parameters
[in]appointer to arg-parser state
Returns
number of parsed arguments

Definition at line 463 of file fg_argparser.c.

464 {
465  return ap->data_size;
466 }

◆ ap_check_mutex()

bool ap_check_mutex ( const struct arg_parser *const  ap,
const struct ap_Mutex_state *const  ms,
const int  i,
int *  conflict 
)

Check a new option record for mutex.

Parameters
[in]appointer to arg-parser state
[in]mspointer to an initialized mutex context
[in]iindex of the option to check for previous occurrences of mutexed options
[in]conflictpointer to a single integer value. This will contain the conflicting record position, if a conflict has been found
Returns
retrun true if conflict according to the state given by ms has occurred, otherwise flase

Definition at line 527 of file fg_argparser.c.

530 {
531  if(ap->num_mutex != ms->num_mutex)
532  return false;
533 
534  *conflict = 0;
535 
536  if (i < 0 || i >= ap_arguments(ap) || !ap->num_mutex)
537  return false;
538 
539  int index = ap->data[i].option_index;
540  for (int *mutex = ap->options[index].mutex; mutex && *mutex; mutex++) {
541  if (ms->seen_records[*mutex-1]) {
542  *conflict = ms->seen_records[*mutex-1]-1;
543  if (ap->data[*conflict].option_index != index)
544  return true;
545  else
546  *conflict = 0;
547  }
548  }
549 
550  return false;
551 }

◆ ap_code()

int ap_code ( const struct arg_parser *const  ap,
const int  i 
)

Returns the code of a parsed option with given index.

Parameters
[in]appointer to arg-parser state
[in]iindex of the parsed option
Returns
code of parsed option at index i. If this is a non-option, it returns 0

Definition at line 468 of file fg_argparser.c.

469 {
470  if (i >= 0 && i < ap_arguments(ap)) {
471  int index = ap->data[i].option_index;
472  return ap->options[index].code;
473  } else {
474  return false;
475  }
476 }

◆ ap_error()

const char* ap_error ( const struct arg_parser *const  ap)

Get the string containing errors encountered during parsing.

Parameters
[in]appointer to arg-parser state
Returns
error string. If no errors occurred, this returns null

Definition at line 458 of file fg_argparser.c.

459 {
460  return ap->error;
461 }

◆ ap_free()

void ap_free ( struct arg_parser *const  ap)

Free internal state of arg-parser.

Parameters
[in]appointer to arg-parser state

Definition at line 448 of file fg_argparser.c.

449 {
450  free_data(ap);
451  if (ap->error) {
452  free(ap->error);
453  ap->error = 0;
454  }
455  ap->error_size = 0;
456 }

◆ ap_free_mutex_state()

void ap_free_mutex_state ( struct ap_Mutex_state *const  ms)

Free a mutex context.

Parameters
[in]mspointer to an initialized mutex context

Definition at line 583 of file fg_argparser.c.

584 {
585  if (ms->seen_records) {
586  free(ms->seen_records);
587  ms->seen_records = 0;
588  ms->num_mutex = 0;
589  }
590 }

◆ ap_init()

bool ap_init ( struct arg_parser *const  ap,
const int  argc,
const char *const  argv[],
const struct ap_Option  options[],
const char  in_order 
)

Initialize the arg-parser given command line and user-defined options.

Parameters
[in]appointer to arg-parser state
[in]argcnumber of command line arguments
[in]argvarray of command line argument strings
[in]optionsarray of user-defined options to parse for. The last entry of the array needs to have '0' members. This array will be copied over to the arg-parser state ap.
[in]in_orderif set to true, arguments are stored in the order in which they appear. If false, non-option arguments are stored after options
Returns
return true for success, or false for failure

Definition at line 374 of file fg_argparser.c.

377 {
378  const char **non_options = 0; /* skipped non-options */
379  int non_options_size = 0; /* number of skipped non-options */
380  int argind = 1; /* index in argv */
381 
382  if (!copy_options(ap,options))
383  return false;
384 
385  ap->num_mutex = get_mutex_count(options);
386 
387  ap->data = 0;
388  ap->error = 0;
389  ap->data_size = 0;
390  ap->error_size = 0;
391  if (argc < 2 || !argv || !options)
392  return true;
393 
394  while (argind < argc) {
395  const unsigned char ch1 = argv[argind][0];
396  const unsigned char ch2 = (ch1 ? argv[argind][1] : 0);
397 
398  if (ch1 == '-' && ch2) { /* we found an option */
399  const char *const opt = argv[argind];
400  const char *const arg =
401  (argind + 1 < argc) ? argv[argind + 1] : 0;
402  if (ch2 == '-') {
403  if (!argv[argind][2]) {
404  ++argind; /* we found "--" */
405  break;
406  } else {
407  if (!parse_long_option
408  (ap, opt, arg, options, &argind))
409  return false;
410  }
411  } else {
412  if (!parse_short_option
413  (ap, opt, arg, options, &argind))
414  return false;
415  }
416  if (ap->error)
417  break;
418  } else {
419  if (!in_order) {
420  void *tmp = ap_resize_buffer(non_options, (non_options_size + 1) *
421  sizeof *non_options);
422  if (!tmp)
423  return false;
424  non_options = (const char **)tmp;
425  non_options[non_options_size++] = argv[argind++];
426  } else if (!push_back_record(ap, ap->num_options, false, argv[argind++])) {
427  return false;
428  }
429  }
430  }
431 
432  if (ap->error) {
433  free_data(ap);
434  } else {
435  for (int i = 0; i < non_options_size; ++i)
436  if (!push_back_record(ap, ap->num_options, false, non_options[i]))
437  return false;
438  while (argind < argc)
439  if (!push_back_record(ap, ap->num_options, false, argv[argind++]))
440  return false;
441  }
442 
443  if (non_options)
444  free(non_options);
445  return true;
446 }

◆ ap_init_mutex_state()

bool ap_init_mutex_state ( const struct arg_parser *const  ap,
struct ap_Mutex_state *const  ms 
)

Initialize a new mutex state table.

This can be seen as a separate context for checking mutex. Thus, by initializing more than one mutex state, mutual exclusions of options may be evaluated in independent contexts.

Parameters
[in]appointer to arg-parser state
[in]mspointer to a new mutex context. It can be used in the following to check and set mutual exclusions
Returns
return true for success, or false for failure

Definition at line 516 of file fg_argparser.c.

518 {
519  ms->seen_records = malloc(sizeof(int)*ap->num_mutex);
520  if(!ap->num_mutex || !ms->seen_records)
521  return false;
522  memset(ms->seen_records,0,sizeof(int)*ap->num_mutex);
523  ms->num_mutex = ap->num_mutex;
524  return true;
525 }

◆ ap_is_used()

bool ap_is_used ( const struct arg_parser *const  ap,
int  code 
)

Returns true if the option specified by code was given at least once.

Parameters
[in]appointer to arg-parser state
[in]codecode of the option to check return return true if the option specified by code has been parsed, otherwise false

Definition at line 503 of file fg_argparser.c.

504 {
505  bool ret = false;
506 
507  for (int i=0; i < ap->data_size; i++)
508  if (ap_code(ap, i) == code) {
509  ret = true;
510  break;
511  }
512 
513  return ret;
514 }

◆ ap_opt_string()

const char* ap_opt_string ( const struct arg_parser *const  ap,
const int  i 
)

Get the real command line option string (may be the short or long version).

Parameters
[in]appointer to arg-parser state
[in]iindex of the parsed option
Returns
raw option string as seen on cmdline

Definition at line 486 of file fg_argparser.c.

487 {
488  if (i >= 0 && i < ap_arguments(ap))
489  return ap->data[i].opt_string;
490  else
491  return "";
492 }

◆ ap_option()

const struct ap_Option* ap_option ( const struct arg_parser *const  ap,
const int  i 
)

Get the user-defined option for a given record position.

Parameters
[in]appointer to arg-parser state
[in]iindex of the parsed option
Returns
pointer to the ap_Option struct of the parsed option at index i

Definition at line 494 of file fg_argparser.c.

496 {
497  if (i >= 0 && i < ap_arguments(ap))
498  return &ap->options[ap->data[i].option_index];
499  else
500  return false;
501 }

◆ ap_reset_mutex()

void ap_reset_mutex ( struct ap_Mutex_state *const  ms)

Reset a mutex context.

Parameters
[in]mspointer to an initialized mutex context

Definition at line 578 of file fg_argparser.c.

579 {
580  memset(ms->seen_records,0,sizeof(int)*ms->num_mutex);
581 }

◆ ap_set_check_mutex()

bool ap_set_check_mutex ( const struct arg_parser *const  ap,
struct ap_Mutex_state *const  ms,
const int  i,
int *  conflict 
)

Check a new option record for mutex and register it at the same time.

Parameters
[in]appointer to arg-parser state
[in]mspointer to an initialized mutex context
[in]iindex of the option to register in the mutex state ms
[in]conflictpointer to a single integer value. This will contain the conflicting record position, if a conflict has been found
Returns
return true if conflict according to the state given by ms has occurred, otherwise false

Definition at line 569 of file fg_argparser.c.

572 {
573  bool ret = ap_check_mutex(ap, ms, i, conflict);
574  ap_set_mutex(ap, ms, i);
575  return ret;
576 }

◆ ap_set_mutex()

bool ap_set_mutex ( const struct arg_parser *const  ap,
struct ap_Mutex_state *const  ms,
const int  i 
)

Register an option record in a mutex context.

Parameters
[in]appointer to arg-parser state
[in]mspointer to an initialized mutex context
[in]iindex of the option to register in the mutex state ms
Returns
return true for success, or false for failure

Definition at line 553 of file fg_argparser.c.

555 {
556  if(ap->num_mutex != ms->num_mutex)
557  return false;
558 
559  if (i < 0 || i >= ap_arguments(ap) || !ap->num_mutex)
560  return false;
561 
562  int index = ap->data[i].option_index;
563  for (int *mutex = ap->options[index].mutex; mutex && *mutex; mutex++)
564  ms->seen_records[*mutex-1] = i+1;
565 
566  return true;
567 }
get_mutex_count
static int get_mutex_count(const struct ap_Option options[])
Get the number of mutex in the option definitions.
Definition: fg_argparser.c:321
arg_parser::error_size
int error_size
Real size of the error string.
Definition: fg_argparser.h:85
ap_code
int ap_code(const struct arg_parser *const ap, const int i)
Returns the code of a parsed option with given index.
Definition: fg_argparser.c:468
ap_Mutex_state::seen_records
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
ap_no
@ ap_no
Option without argument (flag).
Definition: fg_argparser.h:37
ap_Option::mutex
int * mutex
Null-terminated array of mutex IDs (greater zero) this option belongs to.
Definition: fg_argparser.h:59
arg_parser::num_mutex
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:87
parse_long_option
static bool parse_long_option(struct arg_parser *const ap, const char *const opt, const char *const arg, const struct ap_Option options[], int *const argindp)
Parses a long option and adds it to the record of arg-parser ap.
Definition: fg_argparser.c:153
arg_parser::data
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
ap_yes
@ ap_yes
Argument required.
Definition: fg_argparser.h:39
ap_check_mutex
bool ap_check_mutex(const struct arg_parser *const ap, const struct ap_Mutex_state *const ms, const int i, int *conflict)
Check a new option record for mutex.
Definition: fg_argparser.c:527
copy_options
static bool copy_options(struct arg_parser *const ap, const struct ap_Option options[])
Copy options into the arg-parser ap.
Definition: fg_argparser.c:341
ap_Option::code
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
mutex
pthread_mutex_t mutex
Definition: daemon.c:93
arg_parser::data_size
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
free_data
static void free_data(struct arg_parser *const ap)
Free all space required by the arg-parser ap.
Definition: fg_argparser.c:122
push_back_record
static bool push_back_record(struct arg_parser *const ap, const int option_index, bool long_opt, const char *const argument)
Store a parsed option in the state of the arg-parser given by ap.
Definition: fg_argparser.c:66
arg_parser::num_options
int num_options
Number of known options.
Definition: fg_argparser.h:81
ap_resize_buffer
static void * ap_resize_buffer(void *buf, const int min_size)
Assure at least a minimum size for buffer buf.
Definition: fg_argparser.c:48
ap_arguments
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
ap_Record::argument
char * argument
Argument string (may be empty).
Definition: fg_argparser.h:67
arg_parser::error
char * error
Contains errors encountered during parsing.
Definition: fg_argparser.h:79
parse_short_option
static bool parse_short_option(struct arg_parser *const ap, const char *const opt, const char *const arg, const struct ap_Option options[], int *const argindp)
Parses a short option and adds it to the record of arg-parser ap.
Definition: fg_argparser.c:242
ap_Record::option_index
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
ap_maybe
@ ap_maybe
Optional Argument.
Definition: fg_argparser.h:41
ap_Mutex_state::num_mutex
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
arg_parser::options
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
ap_set_mutex
bool ap_set_mutex(const struct arg_parser *const ap, struct ap_Mutex_state *const ms, const int i)
Register an option record in a mutex context.
Definition: fg_argparser.c:553
ap_Record::opt_string
char * opt_string
Observed opt string (maybe the long or the short version).
Definition: fg_argparser.h:65