1 /*
2  * Copyright (c) 2018 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stddef.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "bs_cmd_line.h"
10 #include "bs_dynargs.h"
11 #include "bs_tracing.h"
12 
13 // internal:
14 static int used_args;
15 static int args_aval;
16 #define ARGS_ALLOC_CHUNK_SIZE 20
17 
bs_cleanup_dynargs(bs_args_struct_t ** args_struct)18 void bs_cleanup_dynargs(bs_args_struct_t **args_struct)
19 {
20   if (*args_struct != NULL) { /* LCOV_EXCL_BR_LINE */
21     free(*args_struct);
22     *args_struct = NULL;
23   }
24 }
25 
26 /**
27  * Add a set of command line options to the program.
28  *
29  * Each option to be added is described in one entry of the input <args>
30  * This input must be terminated with an entry containing ARG_TABLE_ENDMARKER.
31  */
bs_add_dynargs(bs_args_struct_t ** all_args,bs_args_struct_t * new_args)32 void bs_add_dynargs(bs_args_struct_t **all_args, bs_args_struct_t *new_args)
33 {
34   int count = 0;
35 
36   while (new_args[count].option != NULL) {
37     count++;
38   }
39   count++; /*for the end marker*/
40 
41   if (used_args + count >= args_aval) {
42     int growby = count;
43     /* reallocs are expensive let's do them only in big chunks */
44     if (growby < ARGS_ALLOC_CHUNK_SIZE) {
45       growby = ARGS_ALLOC_CHUNK_SIZE;
46     }
47 
48     *all_args = realloc(*all_args, (args_aval + growby)*sizeof(bs_args_struct_t));
49     args_aval += growby;
50     /* LCOV_EXCL_START */
51     if (*all_args == NULL) {
52       bs_trace_error_line("Could not allocate memory");
53     }
54     /* LCOV_EXCL_STOP */
55   }
56 
57   memcpy(&(*all_args)[used_args], new_args, count*sizeof(bs_args_struct_t));
58 
59   used_args += count - 1;
60   /*
61    * -1 as the end marker should be overwritten next time something
62    * is added
63    */
64 }
65