To the outside world, almost nothing changes as DARY_LEN is emulated.
However, static initializers are no longer possible, so DARY_ALLOC
is gone.
The current implementation is not elegant. It will be improved soon.
} else if (item->cls == CC_DYNAMIC) {
ptr = * (void**) ptr;
if (ptr) {
- int real_nr = DARY_LEN(ptr);
+ int real_nr = GARY_SIZE(ptr);
bprintf(fb, "N%d ", real_nr);
for (i=0; i<real_nr; i++)
dump_basic(fb, ptr + i * size, type, &item->u);
* UCW Library -- Configuration files: interpreter
*
* (c) 2001--2006 Robert Spalek <robert@ucw.cz>
- * (c) 2003--2012 Martin Mares <mj@ucw.cz>
+ * (c) 2003--2014 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
#include <ucw/getopt.h>
#include <ucw/conf-internal.h>
#include <ucw/clists.h>
+#include <ucw/gary.h>
#include <string.h>
#include <stdio.h>
#undef T
char *cf_type_names[] = { "int", "u64", "double", "ip", "string", "lookup", "user" };
-#define DARY_HDR_SIZE ALIGN_TO(sizeof(uns), CPU_STRUCT_ALIGN)
-
static char *
interpret_set_dynamic(struct cf_item *item, int number, char **pars, void **ptr)
{
enum cf_type type = item->type;
+ uns size = cf_type_size(type, item->u.utype);
cf_journal_block(ptr, sizeof(void*));
// boundary checks done by the caller
- uns size = cf_type_size(item->type, item->u.utype);
- *ptr = cf_malloc(DARY_HDR_SIZE + number * size) + DARY_HDR_SIZE;
- DARY_LEN(*ptr) = number;
+ struct gary_allocator *a = gary_new_allocator_mp(cf_get_pool()); // FIXME: One copy should be enough
+ *ptr = gary_init(size, number, a);
return cf_parse_ary(number, pars, *ptr, type, &item->u);
}
void *old_p = *ptr;
uns size = cf_type_size(item->type, item->u.utype);
ASSERT(size >= sizeof(uns));
- int old_nr = old_p ? DARY_LEN(old_p) : 0;
+ int old_nr = old_p ? GARY_SIZE(old_p) : 0;
int taken = MIN(number, ABS(item->number)-old_nr);
*processed = taken;
// stretch the dynamic array
- void *new_p = cf_malloc(DARY_HDR_SIZE + (old_nr + taken) * size) + DARY_HDR_SIZE;
- DARY_LEN(new_p) = old_nr + taken;
+ struct gary_allocator *a = gary_new_allocator_mp(cf_get_pool()); // FIXME: One copy should be enough
+ void *new_p = gary_init(size, old_nr + taken, a);
cf_journal_block(ptr, sizeof(void*));
*ptr = new_p;
if (op == OP_APPEND) {
clist_init(ptr);
} else if (item->cls == CC_DYNAMIC) {
cf_journal_block(ptr, sizeof(void *));
- static uns zero = 0;
- * (void**) ptr = (&zero) + 1;
+ * (void**) ptr = GARY_FOREVER_EMPTY;
} else if (item->cls == CC_STATIC && item->type == CT_STRING) {
cf_journal_block(ptr, item->number * sizeof(char*));
bzero(ptr, item->number * sizeof(char*));
* UCW Library -- Configuration files: sections
*
* (c) 2001--2006 Robert Spalek <robert@ucw.cz>
- * (c) 2003--2012 Martin Mares <mj@ucw.cz>
+ * (c) 2003--2014 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
#include <ucw/conf-internal.h>
#include <ucw/clists.h>
#include <ucw/binsearch.h>
+#include <ucw/gary.h>
#include <string.h>
clist_init(ptr + (uintptr_t) ci->ptr);
else if (ci->cls == CC_DYNAMIC) {
void **dyn = ptr + (uintptr_t) ci->ptr;
- if (!*dyn) { // replace NULL by an empty array
- static uns zero = 0;
- *dyn = (&zero) + 1;
- }
+ if (!*dyn) // replace NULL by an empty array
+ *dyn = GARY_FOREVER_EMPTY;
}
if (sec->init) {
char *msg = sec->init(ptr);
* Insane tester of reading configuration files
*
* (c) 2006 Robert Spalek <robert@ucw.cz>
- * (c) 2012 Martin Mares <mj@ucw.cz>
+ * (c) 2012--2014 Martin Mares <mj@ucw.cz>
*/
#include <ucw/lib.h>
#include <ucw/getopt.h>
#include <ucw/clists.h>
#include <ucw/fastbuf.h>
+#include <ucw/gary.h>
#include <stdlib.h>
#include <stdio.h>
double *list;
};
-static struct sub_sect_1 sec1 = { {}, "Charlie", 0, "WBAFC", { 0, -1}, DARY_ALLOC(double, 3, 1e4, -1e-4, 8) };
+static struct sub_sect_1 sec1 = { {}, "Charlie", 0, "WBAFC", { 0, -1}, NULL };
static char *
init_sec_1(struct sub_sect_1 *s)
};
static uns nr1 = 15;
-static int *nrs1 = DARY_ALLOC(int, 5, 5, 4, 3, 2, 1);
+static int *nrs1;
static int nrs2[5];
static char *str1 = "no worries";
-static char **str2 = DARY_ALLOC(char *, 2, "Alice", "Bob");
+static char **str2;
static u64 u1 = 0xCafeBeefDeadC00ll;
static double d1 = -1.1;
static clist secs;
static time_t t1, t2;
static u32 ip;
-static int *look = DARY_ALLOC(int, 2, 2, 1);
+static int *look;
static u16 numbers[10] = { 2, 100, 1, 5 };
static u32 bitmap1 = 0xff;
static u32 bitmap2 = 3;
cf_declare_section("top", &cf_top, 0);
cf_def_file = "ucw/conf-test.cf";
+ // Create and initialize dynamic arrays
+ GARY_INIT(nrs1, 6);
+ memcpy(nrs1, (int []) { 5, 5, 4, 3, 2, 1 }, 6 * sizeof(int));
+ GARY_INIT(str2, 2);
+ str2[0] = "Alice";
+ str2[1] = "Bob";
+ GARY_INIT(look, 2);
+ look[0] = 2;
+ look[1] = 1;
+ GARY_INIT(sec1.list, 3);
+ memcpy(sec1.list, (double []) { 1e4, -1e-4, 8 }, 3 * sizeof(double));
+
int opt;
while ((opt = cf_getopt(argc, argv, short_opts, long_opts, NULL)) >= 0)
switch (opt) {
* UCW Library -- Configuration files
*
* (c) 2001--2006 Robert Spalek <robert@ucw.cz>
- * (c) 2003--2012 Martin Mares <mj@ucw.cz>
+ * (c) 2003--2014 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
#define _UCW_CONF_H
#include <ucw/clists.h>
+#include <ucw/gary.h>
#ifdef CONFIG_UCW_CLEAN_ABI
#define cf_close_group ucw_cf_close_group
**/
#define CF_ANY_NUM -0x7fffffff
-#define DARY_LEN(a) ((uns*)a)[-1] /** Length of an dynamic array. **/
-#define DARY_ALLOC(type,len,val...) ((struct { byte pad[ALIGN_TO(sizeof(uns), CPU_STRUCT_ALIGN) - sizeof(uns)]; uns l; type a[len]; }) { .l = len, .a = { val } }).a
- // creates a static instance of a dynamic array
+#define DARY_LEN(a) GARY_SIZE(a) /** Length of an dynamic array. An alias for `GARY_SIZE`. **/
/***
* [[alloc]]
*Dynamic arrays*::
Similar to static array, but you provide pointer
to pointer to the given item (eg. if you want dynamic array of
- integers, you give `**int`). The parser allocates an array of needed
- size. You can use the <<def_DARY_LEN,`DARY_LEN`>> macro to find out
- the number of elements actually loaded.
+ integers, you give `**int`). The parser allocates a growing array
+ (see `gary.h`) of the required size.
+
If you want dynamic array of strings, you would use:
+
#include <string.h>
+struct gary_hdr gary_empty_hdr;
+
void *
gary_init(size_t elt_size, size_t num_elts, struct gary_allocator *allocator)
{
}
}
+/* A forever empty gary. Used internally. */
+
+extern struct gary_hdr gary_empty_hdr;
+#define GARY_FOREVER_EMPTY GARY_BODY(&gary_empty_hdr)
+
/* Type-agnostic interface. Currently it's recommended for internal use only. */
#define GARY_PUSH_GENERIC(ptr) ({ \