utarray question: pre-allocated itens

30 views
Skip to first unread message

silvioprog

unread,
Mar 11, 2017, 9:31:50 AM3/11/17
to uth...@googlegroups.com
Hello dudes,

Consider the following code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utarray.h"

struct upload {
const char *filename;
FILE *stream;
};

static void upload_init(void *p) {
struct upload *up = p;
up->stream = fopen(up->filename, "r");
}

static void upload_dtor(void *p) {
struct upload *up = p;
fclose((up)->stream);
free(up);
}

UT_icd upload_icd = {sizeof(struct upload), &upload_init, NULL, &upload_dtor};

int main() {
char line[10]; // <- just for tests
struct upload *up, *p;
UT_array *ups;
utarray_new(ups, &upload_icd);

// upload 1
up = malloc(sizeof(struct upload));
up->filename = "foo.txt";
utarray_push_back(ups, up);

// upload 2
up = malloc(sizeof(struct upload));
up->filename = "bar.txt";
utarray_push_back(ups, up);

for (p = (struct upload *) utarray_front(ups); p != NULL; p = (struct upload *) utarray_next(ups, p)) {
printf("filename: %s\n", p->filename);
while (fgets(line, sizeof(line), up->file))
printf("content: %s\n", line);
}

utarray_free(ups);
return 0;
}
In the real scenario "up" if allocated in a scope and its reference reused in other scopes, so its life cycle must be managed outside utarray.

Therefore, how do I use utarray with pre-allocated itens? (I took a look its sources and can't find any utarray_push_back_ptr :-/)

Thank you!

--
Silvio Clécio

silvioprog

unread,
Mar 11, 2017, 9:43:03 AM3/11/17
to uth...@googlegroups.com
Oops, sorry. It seems I need a utlist instead of utarray. I'm going to check it ... ^^'
--
Silvio Clécio

silvioprog

unread,
Mar 11, 2017, 10:12:16 AM3/11/17
to uth...@googlegroups.com
Solved. Please skip my previous e-mails and sorry the noise. :-)

Using utlist (thanks this awesome structure!):

#include <stdio.h>
#include <stdlib.h>
#include "utlist.h"

struct upload {
const char *filename;
FILE *stream;
    struct upload *next;
};

typedef void (*uploads_foreach_callback)(void *cls, struct upload *item);

struct upload *uploads_add(struct upload **list, const char *filename) {
struct upload *item;
if (NULL == list)
return NULL;
item = malloc(sizeof(struct upload));
if (NULL == item)
return NULL;
item->filename = filename;
item->stream = fopen(item->filename, "r");
LL_APPEND(*list, item);
return item;
}

void uploads_foreach(struct upload *list, uploads_foreach_callback callback, void *callback_cls) {
struct upload *item;
if (NULL != list && NULL != callback)
LL_FOREACH(list, item) {
callback(callback_cls, item);
}
}

void uploads_cleanup(struct upload *list) {
struct upload *item, *tmp;
if (NULL != list)
LL_FOREACH_SAFE(list, item, tmp) {
LL_DELETE(list, item);
fclose(item->stream);
free(item);
}
}

/* example */

static void example_uploads_foreach(void *cls, struct upload *item) {
char line[1024];
printf("filename: %s\n", item->filename);
while (fgets(line, sizeof(line), item->stream))

printf("content: %s\n", line);
}

int main() {
struct upload *list = NULL;
// upload 1
uploads_add(&list, "foo.txt"); // up = upload_add: finally I can use the "up" reference outside the list! :-)
// upload 2
uploads_add(&list, "bar.txt");
uploads_foreach(list, &example_uploads_foreach, NULL);
uploads_cleanup(list);
return 0;
}
--
Silvio Clécio
Reply all
Reply to author
Forward
0 new messages