src/rrd_args.[ch]: Implement data structure for more powerful RRD argument construction.
[collection4.git] / src / rrd_args.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
4
5 #include "rrd_args.h"
6
7 rrd_args_t *ra_create (void) /* {{{ */
8 {
9   rrd_args_t *ra;
10
11   ra = malloc (sizeof (*ra));
12   if (ra == NULL)
13     return (NULL);
14   memset (ra, 0, sizeof (*ra));
15
16   ra->options = array_create ();
17   ra->data    = array_create ();
18   ra->calc    = array_create ();
19   ra->draw    = array_create ();
20
21   if ((ra->options == NULL)
22       || (ra->data == NULL)
23       || (ra->calc == NULL)
24       || (ra->draw == NULL))
25   {
26     ra_destroy (ra);
27     return (NULL);
28   }
29
30   return (ra);
31 } /* }}} rrd_args_t *ra_create */
32
33 void ra_destroy (rrd_args_t *ra) /* {{{ */
34 {
35   if (ra == NULL)
36     return;
37
38   array_destroy (ra->options);
39   array_destroy (ra->data);
40   array_destroy (ra->calc);
41   array_destroy (ra->draw);
42
43   free (ra);
44 } /* }}} void ra_destroy */
45
46 int ra_argc (rrd_args_t *ra)
47 {
48   if (ra == NULL)
49     return (-EINVAL);
50
51   return (array_argc (ra->options)
52       + array_argc (ra->data)
53       + array_argc (ra->calc)
54       + array_argc (ra->draw));
55 } /* }}} int ra_argc */
56
57 char **ra_argv (rrd_args_t *ra) /* {{{ */
58 {
59   size_t argc;
60   char **argv;
61
62   size_t pos;
63   int tmp;
64
65   if (ra == NULL)
66     return (NULL);
67
68   tmp = ra_argc (ra);
69   if (tmp < 0)
70     return (NULL);
71   argc = (size_t) tmp;
72
73   argv = calloc (argc + 1, sizeof (*argv));
74   if (argv == NULL)
75     return (NULL);
76
77   pos = 0;
78
79 #define APPEND_FIELD(field) do                                               \
80 {                                                                            \
81   size_t ary_argc;                                                           \
82   char **ary_argv;                                                           \
83                                                                              \
84   ary_argc = (size_t) array_argc (ra->field);                                \
85   ary_argv = array_argv (ra->field);                                         \
86   if ((ary_argc > 0) && (ary_argv != NULL))                                  \
87   {                                                                          \
88     memcpy (argv + pos, ary_argv, ary_argc * sizeof (*ary_argv));            \
89     pos += ary_argc;                                                         \
90     argv[pos] = NULL;                                                        \
91   }                                                                          \
92   free (ary_argv);                                                           \
93 } while (0)
94  
95   APPEND_FIELD (options);
96   APPEND_FIELD (data);
97   APPEND_FIELD (calc);
98   APPEND_FIELD (draw);
99
100 #undef APPEND_FIELD
101
102   return (argv);
103 } /* }}} char **ra_argv */
104
105 /* vim: set sw=2 sts=2 et fdm=marker : */