Flowgrind
Advanced TCP traffic generator
fg_argparser.c File Reference

Command line argument parser. More...

#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "fg_definitions.h"
#include "fg_argparser.h"

Go to the source code of this file.

Functions

static bool add_error (struct arg_parser *const ap, const char *const msg)
 Add an error message to the arg-parser ap. More...
 
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...
 
static void * ap_resize_buffer (void *buf, const int min_size)
 Assure at least a minimum size for buffer buf. 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...
 
static bool copy_options (struct arg_parser *const ap, const struct ap_Option options[])
 Copy options into the arg-parser ap. More...
 
static void free_data (struct arg_parser *const ap)
 Free all space required by the arg-parser ap. More...
 
static int get_mutex_count (const struct ap_Option options[])
 Get the number of mutex in the option definitions. More...
 
static int get_num_options (const struct ap_Option options[])
 Determines number of options in options. More...
 
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. More...
 
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. More...
 
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. More...
 

Detailed Description

Command line argument parser.

Definition in file fg_argparser.c.

Function Documentation

static bool add_error ( struct arg_parser *const  ap,
const char *const  msg 
)
static

Add an error message to the arg-parser ap.

Parameters
[in]appointer to the arg-parser state
[in]msgerror string
Returns
return true for success, or false for failure

Definition at line 104 of file fg_argparser.c.

105 {
106  const int len = strlen(msg);
107  void *tmp = ap_resize_buffer(ap->error, ap->error_size + len + 1);
108  if (!tmp)
109  return false;
110  ap->error = (char *)tmp;
111  strncpy(ap->error + ap->error_size, msg, len + 1);
112  ap->error_size += len;
113 
114  return true;
115 }
char * error
Contains errors encountered during parsing.
Definition: fg_argparser.h:79
int error_size
Real size of the error string.
Definition: fg_argparser.h:85
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
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 }
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
char * argument
Argument string (may be empty).
Definition: fg_argparser.h:67
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
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 }
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
int * mutex
Null-terminated array of mutex IDs (greater zero) this option belongs to.
Definition: fg_argparser.h:59
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:87
pthread_mutex_t mutex
Definition: daemon.c:89
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
char * error
Contains errors encountered during parsing.
Definition: fg_argparser.h:79
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 }
static void free_data(struct arg_parser *const ap)
Free all space required by the arg-parser ap.
Definition: fg_argparser.c:122
char * error
Contains errors encountered during parsing.
Definition: fg_argparser.h:79
int error_size
Real size of the error string.
Definition: fg_argparser.h:85
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 }
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
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 }
static int get_mutex_count(const struct ap_Option options[])
Get the number of mutex in the option definitions.
Definition: fg_argparser.c:321
int num_options
Number of known options.
Definition: fg_argparser.h:81
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:87
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
static void free_data(struct arg_parser *const ap)
Free all space required by the arg-parser ap.
Definition: fg_argparser.c:122
char * error
Contains errors encountered during parsing.
Definition: fg_argparser.h:79
int error_size
Real size of the error string.
Definition: fg_argparser.h:85
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
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
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
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
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
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:87
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
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 }
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
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
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 }
char * opt_string
Observed opt string (maybe the long or the short version).
Definition: fg_argparser.h:65
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
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 }
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
static void* ap_resize_buffer ( void *  buf,
const int  min_size 
)
static

Assure at least a minimum size for buffer buf.

Parameters
[in]bufpointer to buffer
[in]min_sizeminimum size buf should hold in bytes
Returns
pointer to the newly allocated buffer

Definition at line 48 of file fg_argparser.c.

49 {
50  if (buf)
51  buf = realloc(buf, min_size);
52  else
53  buf = malloc(min_size);
54  return buf;
55 }
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 }
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
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
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 }
int * seen_records
A table containing for each mutex the last seen option record.
Definition: fg_argparser.h:93
int * mutex
Null-terminated array of mutex IDs (greater zero) this option belongs to.
Definition: fg_argparser.h:59
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:87
pthread_mutex_t mutex
Definition: daemon.c:89
int ap_arguments(const struct arg_parser *const ap)
Number of arguments parsed (may be different from argc).
Definition: fg_argparser.c:463
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
int num_mutex
The number of defined mutex.
Definition: fg_argparser.h:95
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
static bool copy_options ( struct arg_parser *const  ap,
const struct ap_Option  options[] 
)
static

Copy options into the arg-parser ap.

This is a deep copy including strings and arrays.

Parameters
[in]aparg-parser
[in]optionsoptions struct to copy
Returns
return true for success, or false for failure

Definition at line 341 of file fg_argparser.c.

343 {
344 
345  ap->num_options = get_num_options(options);
346  if (!ap->num_options)
347  return false;
348  ap->options = malloc(sizeof(struct ap_Option)*ap->num_options);
349  if (!ap->options)
350  return false;
351 
352  for (int i=0; i < ap->num_options; i++) {
353  ap->options[i] = options[i];
354  if (options[i].name)
355  ap->options[i].name = strdup(options[i].name);
356 
357  if (options[i].mutex) {
358  /* get number of mutex items */
359  int num;
360  for (num = 0; options[i].mutex[num]; num++);
361 
362  /* now copy into new array */
363  ap->options[i].mutex = malloc(sizeof(int)*
364  (num+1));
365  if (!ap->options[i].mutex)
366  return false;
367  for (int e=0; e<=num; e++)
368  ap->options[i].mutex[e] = options[i].mutex[e];
369  }
370  }
371  return true;
372 }
int * mutex
Null-terminated array of mutex IDs (greater zero) this option belongs to.
Definition: fg_argparser.h:59
static int get_num_options(const struct ap_Option options[])
Determines number of options in options.
Definition: fg_argparser.c:306
int num_options
Number of known options.
Definition: fg_argparser.h:81
Defines a valid command line option.
Definition: fg_argparser.h:45
pthread_mutex_t mutex
Definition: daemon.c:89
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
char * name
Long option name (maybe null).
Definition: fg_argparser.h:49
static void free_data ( struct arg_parser *const  ap)
static

Free all space required by the arg-parser ap.

Parameters
[in]appointer to the arg-parser state

Definition at line 122 of file fg_argparser.c.

123 {
124  for (int i = 0; i < ap->data_size; ++i) {
125  free(ap->data[i].argument);
126  free(ap->data[i].opt_string);
127  }
128  if (ap->data) {
129  free(ap->data);
130  ap->data = 0;
131  }
132  ap->data_size = 0;
133 
134  for (int i = 0; i < ap->num_options; ++i) {
135  free(ap->options[i].name);
136  free(ap->options[i].mutex);
137  }
138  free(ap->options);
139  ap->num_options = 0;
140 }
int * mutex
Null-terminated array of mutex IDs (greater zero) this option belongs to.
Definition: fg_argparser.h:59
char * opt_string
Observed opt string (maybe the long or the short version).
Definition: fg_argparser.h:65
int num_options
Number of known options.
Definition: fg_argparser.h:81
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
char * argument
Argument string (may be empty).
Definition: fg_argparser.h:67
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
char * name
Long option name (maybe null).
Definition: fg_argparser.h:49
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77
static int get_mutex_count ( const struct ap_Option  options[])
static

Get the number of mutex in the option definitions.

Searching for the greatest mutex ID in all options.

Parameters
[in]optionsarray of user-defined options
Returns
number of mutex in the option definitions

Definition at line 321 of file fg_argparser.c.

322 {
323  int num = 0;
324 
325  for (int i=0; options[i].code; i++)
326  for (int *mutex = options[i].mutex; mutex && *mutex; mutex++)
327  ASSIGN_MAX(num, *mutex);
328 
329  return num;
330 }
pthread_mutex_t mutex
Definition: daemon.c:89
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
#define ASSIGN_MAX(s, c)
Assign value if it&#39;s greater than current one.
static int get_num_options ( const struct ap_Option  options[])
static

Determines number of options in options.

Counting all options until an option with code 0 is found.

Parameters
[in]optionsarray of user-defined options
Returns
number of options in options

Definition at line 306 of file fg_argparser.c.

307 {
308  int i;
309  for (i=0; options[i].code; i++){}
310  return i;
311 }
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
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 
)
static

Parses a long option and adds it to the record of arg-parser ap.

Parameters
[in]appointer to the arg-parser state
[in]optlong option string
[in]argoption argument string
[in]optionsarray containing all defined options which may be parsed
[in]argindppointer to the index in the command line argument array. The value will be automatically updated
Returns
return true for success, or false for failure

Definition at line 153 of file fg_argparser.c.

157 {
158  unsigned len;
159  int index = -1;
160  char exact = 0, ambig = 0;
161 
162  for (len = 0; opt[len + 2] && opt[len + 2] != '='; ++len) ;
163 
164  /* Test all long options for either exact match or abbreviated matches */
165  for (int i = 0; options[i].code != 0; ++i)
166  if (options[i].name
167  && strncmp(options[i].name, &opt[2], len) == 0) {
168  /* Exact match found */
169  if (strlen(options[i].name) == len) {
170  index = i;
171  exact = 1;
172  break;
173  /* First nonexact match found */
174  } else if (index < 0) {
175  index = i;
176  /* Second or later nonexact match found */
177  } else if (options[index].code != options[i].code ||
178  options[index].has_arg != options[i].has_arg) {
179  ambig = 1;
180  }
181  }
182 
183  if (ambig && !exact) {
184  add_error(ap, "option '");
185  add_error(ap, opt);
186  add_error(ap, "' is ambiguous");
187  return true;
188  }
189 
190  /* nothing found */
191  if (index < 0) {
192  add_error(ap, "unrecognized option '");
193  add_error(ap, opt);
194  add_error(ap, "'");
195  return true;
196  }
197 
198  ++*argindp;
199 
200  /* '--<long_option>=<argument>' syntax */
201  if (opt[len + 2]) {
202  if (options[index].has_arg == ap_no) {
203  add_error(ap, "option '--");
204  add_error(ap, options[index].name);
205  add_error(ap, "' doesn't allow an argument");
206  return true;
207  }
208  if (options[index].has_arg == ap_yes && !opt[len + 3]) {
209  add_error(ap, "option '--");
210  add_error(ap, options[index].name);
211  add_error(ap, "' requires an argument");
212  return true;
213  }
214  return push_back_record(ap, index, true, &opt[len + 3]);
215  }
216 
217  if (options[index].has_arg == ap_yes) {
218  if (!arg || !arg[0]) {
219  add_error(ap, "option '--");
220  add_error(ap, options[index].name);
221  add_error(ap, "' requires an argument");
222  return true;
223  }
224  ++*argindp;
225  return push_back_record(ap, index, true, arg);
226  }
227 
228  return push_back_record(ap, index, true, "");
229 }
Option without argument (flag).
Definition: fg_argparser.h:37
static bool add_error(struct arg_parser *const ap, const char *const msg)
Add an error message to the arg-parser ap.
Definition: fg_argparser.c:104
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
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
Argument required.
Definition: fg_argparser.h:39
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 
)
static

Parses a short option and adds it to the record of arg-parser ap.

Parameters
[in]appointer to the arg-parser state
[in]optlong option string
[in]argoption argument string
[in]optionsarray containing all defined options which may be parsed
[in]argindppointer to the index in the command line argument array. The value will be automatically updated
Returns
return true for success, or false for failure

Definition at line 242 of file fg_argparser.c.

246 {
247  int cind = 1; /* character index in opt */
248 
249  while (cind > 0) {
250  int index = -1;
251  const unsigned char code = opt[cind];
252  char code_str[2];
253  code_str[0] = code;
254  code_str[1] = 0;
255 
256  if (code != 0)
257  for (int i = 0; options[i].code; ++i)
258  if (code == options[i].code) {
259  index = i;
260  break;
261  }
262 
263  if (index < 0) {
264  add_error(ap, "invalid option -- ");
265  add_error(ap, code_str);
266  return true;
267  }
268 
269  /* opt finished */
270  if (opt[++cind] == 0) {
271  ++*argindp;
272  cind = 0;
273  }
274 
275  if (options[index].has_arg != ap_no && cind > 0 && opt[cind]) {
276  if (!push_back_record(ap, index, false, &opt[cind]))
277  return false;
278  ++*argindp;
279  cind = 0;
280  } else if (options[index].has_arg == ap_yes) {
281  if (!arg || !arg[0]) {
282  add_error(ap, "option requires an argument -- ");
283  add_error(ap, code_str);
284  return true;
285  }
286  ++*argindp;
287  cind = 0;
288  if (!push_back_record(ap, index, false, arg))
289  return false;
290  } else if (!push_back_record(ap, index, false, "")) {
291  return false;
292  }
293  }
294 
295  return true;
296 }
Option without argument (flag).
Definition: fg_argparser.h:37
static bool add_error(struct arg_parser *const ap, const char *const msg)
Add an error message to the arg-parser ap.
Definition: fg_argparser.c:104
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
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
Argument required.
Definition: fg_argparser.h:39
static bool push_back_record ( struct arg_parser *const  ap,
const int  option_index,
bool  long_opt,
const char *const  argument 
)
static

Store a parsed option in the state of the arg-parser given by ap.

Parameters
[in]appointer to the arg-parser state
[in]option_indexindex of the option to store
[in]long_opttrue if this option was a long option
[in]argumentargument string for this option (may be empty)
Returns
return true for success, or false for failure

Definition at line 66 of file fg_argparser.c.

68 {
69  const int len = strlen(argument);
70  struct ap_Record *p;
71  void *tmp = ap_resize_buffer(ap->data,
72  (ap->data_size + 1) * sizeof(struct ap_Record));
73  if (!tmp)
74  return false;
75  ap->data = (struct ap_Record *)tmp;
76  p = &(ap->data[ap->data_size]);
78  p->argument = 0;
79  tmp = ap_resize_buffer(p->argument, len + 1);
80  if (!tmp)
81  return false;
82  p->argument = (char *)tmp;
83  strncpy(p->argument, argument, len + 1);
84 
85  if (long_opt) {
86  if (!asprintf(&p->opt_string, "--%s", ap->options[option_index].name))
87  return false;
88  } else {
89  if (!asprintf(&p->opt_string, "-%c", ap->options[option_index].code))
90  return false;
91  }
92 
93  ++ap->data_size;
94  return true;
95 }
char * opt_string
Observed opt string (maybe the long or the short version).
Definition: fg_argparser.h:65
Holds a parsed command line option and its argument.
Definition: fg_argparser.h:63
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
int data_size
Number of parsed records.
Definition: fg_argparser.h:83
int code
Short option letter or code (code != 0).
Definition: fg_argparser.h:47
char * argument
Argument string (may be empty).
Definition: fg_argparser.h:67
struct ap_Option * options
Array containing user-defined options.
Definition: fg_argparser.h:75
char * name
Long option name (maybe null).
Definition: fg_argparser.h:49
int option_index
Index of the option for internal use (e.g.
Definition: fg_argparser.h:69
struct ap_Record * data
Container for parsed cmdline options.
Definition: fg_argparser.h:77