librazor/iterator.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Apr 29 17:00:01 2009 +0100 (2009-04-29)
changeset 361 2523d03a840e
parent 308 f4761f529b9e
child 377 5549419824b4
permissions -rw-r--r--
Add support for preloading lua modules. This is useful both when
providing lua bindings to applications based on librazor and when
producing static binaries using librazor (where otherwise the lua
POSIX library would need to be included as an additional dynamic
object).
krh@248
     1
/*
krh@248
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
krh@248
     3
 * Copyright (C) 2008  Red Hat, Inc
ali@351
     4
 * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
krh@248
     5
 *
krh@248
     6
 * This program is free software; you can redistribute it and/or modify
krh@248
     7
 * it under the terms of the GNU General Public License as published by
krh@248
     8
 * the Free Software Foundation; either version 2 of the License, or
krh@248
     9
 * (at your option) any later version.
krh@248
    10
 *
krh@248
    11
 * This program is distributed in the hope that it will be useful,
krh@248
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
krh@248
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
krh@248
    14
 * GNU General Public License for more details.
krh@248
    15
 *
krh@248
    16
 * You should have received a copy of the GNU General Public License along
krh@248
    17
 * with this program; if not, write to the Free Software Foundation, Inc.,
krh@248
    18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
krh@248
    19
 */
krh@248
    20
krh@248
    21
#define _GNU_SOURCE
krh@248
    22
richard@302
    23
#include <stdarg.h>
krh@248
    24
#include <string.h>
richard@301
    25
#include <assert.h>
richard@301
    26
krh@248
    27
#include "razor-internal.h"
krh@248
    28
#include "razor.h"
krh@248
    29
krh@248
    30
static struct razor_package_iterator *
krh@248
    31
razor_package_iterator_create_with_index(struct razor_set *set,
krh@248
    32
					 struct list *index)
krh@248
    33
{
krh@248
    34
	struct razor_package_iterator *pi;
krh@248
    35
krh@248
    36
	pi = zalloc(sizeof *pi);
krh@248
    37
	pi->set = set;
krh@248
    38
	pi->index = index;
krh@248
    39
krh@248
    40
	return pi;
krh@248
    41
}
krh@248
    42
jbowes@278
    43
static struct razor_package_iterator *
jbowes@278
    44
razor_package_iterator_create_empty(struct razor_set *set)
jbowes@278
    45
{
jbowes@278
    46
	struct razor_package_iterator *pi;
jbowes@278
    47
	return zalloc(sizeof *pi);
jbowes@278
    48
}
jbowes@278
    49
krh@269
    50
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    51
razor_package_iterator_create(struct razor_set *set)
krh@248
    52
{
krh@248
    53
	struct razor_package_iterator *pi;
krh@248
    54
richard@301
    55
	assert (set != NULL);
richard@301
    56
krh@248
    57
	pi = zalloc(sizeof *pi);
krh@248
    58
	pi->set = set;
krh@248
    59
	pi->end = set->packages.data + set->packages.size;
krh@248
    60
	pi->package = set->packages.data;
krh@248
    61
krh@248
    62
	return pi;
krh@248
    63
}
krh@248
    64
krh@269
    65
RAZOR_EXPORT void
krh@248
    66
razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
krh@248
    67
					 struct razor_set *set,
krh@248
    68
					 struct razor_property *property)
krh@248
    69
{
richard@301
    70
	assert (pi != NULL);
richard@301
    71
	assert (set != NULL);
richard@301
    72
	assert (property != NULL);
richard@301
    73
krh@248
    74
	memset(pi, 0, sizeof *pi);
krh@248
    75
	pi->set = set;
krh@248
    76
	pi->index = list_first(&property->packages, &set->package_pool);
krh@248
    77
}
krh@248
    78
krh@269
    79
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    80
razor_package_iterator_create_for_property(struct razor_set *set,
krh@248
    81
					   struct razor_property *property)
krh@248
    82
{
krh@248
    83
	struct list *index;
krh@248
    84
richard@301
    85
	assert (set != NULL);
richard@301
    86
	assert (property != NULL);
richard@301
    87
krh@248
    88
	index = list_first(&property->packages, &set->package_pool);
krh@248
    89
	return razor_package_iterator_create_with_index(set, index);
krh@248
    90
}
krh@248
    91
krh@269
    92
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    93
razor_package_iterator_create_for_file(struct razor_set *set,
krh@248
    94
				       const char *filename)
krh@248
    95
{
krh@248
    96
	struct razor_entry *entry;
krh@248
    97
	struct list *index;
krh@248
    98
richard@301
    99
	assert (set != NULL);
richard@301
   100
	assert (filename != NULL);
richard@301
   101
krh@248
   102
	entry = razor_set_find_entry(set, set->files.data, filename);
krh@248
   103
	if (entry == NULL)
jbowes@278
   104
		return razor_package_iterator_create_empty(set);
krh@248
   105
krh@248
   106
	index = list_first(&entry->packages, &set->package_pool);
krh@248
   107
	return razor_package_iterator_create_with_index(set, index);
krh@248
   108
}
krh@248
   109
richard@302
   110
/**
richard@302
   111
 * razor_package_iterator_next:
richard@302
   112
 * @pi: a %razor_package_iterator
richard@302
   113
 * @package: a %razor_package
richard@302
   114
 *
richard@302
   115
 * Gets the next iteratr along with any vararg data.
krh@308
   116
 * The vararg must be terminated with %RAZOR_DETAIL_LAST.
richard@302
   117
 *
richard@307
   118
 * Example: razor_package_iterator_next (pi, package,
richard@307
   119
 *					 RAZOR_DETAIL_NAME, &name,
richard@307
   120
 *					 RAZOR_DETAIL_LAST);
richard@302
   121
 **/
krh@269
   122
RAZOR_EXPORT int
krh@248
   123
razor_package_iterator_next(struct razor_package_iterator *pi,
richard@302
   124
			    struct razor_package **package, ...)
krh@248
   125
{
richard@302
   126
	va_list args;
krh@248
   127
	int valid;
krh@248
   128
	struct razor_package *p, *packages;
krh@248
   129
richard@301
   130
	assert (pi != NULL);
richard@301
   131
krh@248
   132
	if (pi->package) {
krh@248
   133
		p = pi->package++;
krh@248
   134
		valid = p < pi->end;
krh@248
   135
	} else if (pi->index) {
krh@248
   136
		packages = pi->set->packages.data;
krh@248
   137
		p = &packages[pi->index->data];
krh@248
   138
		pi->index = list_next(pi->index);
krh@248
   139
		valid = 1;
krh@248
   140
	} else
krh@248
   141
		valid = 0;
krh@248
   142
richard@302
   143
	if (valid == 0) {
krh@248
   144
		*package = NULL;
richard@302
   145
		goto out;
krh@248
   146
	}
krh@248
   147
richard@302
   148
	*package = p;
richard@302
   149
richard@302
   150
	va_start(args, NULL);
richard@302
   151
	razor_package_get_details_varg (pi->set, p, args);
richard@302
   152
	va_end (args);
richard@302
   153
out:
krh@248
   154
	return valid;
krh@248
   155
}
krh@248
   156
krh@269
   157
RAZOR_EXPORT void
krh@248
   158
razor_package_iterator_destroy(struct razor_package_iterator *pi)
krh@248
   159
{
richard@301
   160
	assert (pi != NULL);
richard@301
   161
krh@248
   162
	if (pi->free_index)
krh@248
   163
		free(pi->index);
krh@248
   164
krh@248
   165
	free(pi);
krh@248
   166
}
krh@248
   167
krh@269
   168
RAZOR_EXPORT struct razor_property_iterator *
krh@248
   169
razor_property_iterator_create(struct razor_set *set,
krh@248
   170
			       struct razor_package *package)
krh@248
   171
{
krh@248
   172
	struct razor_property_iterator *pi;
krh@248
   173
richard@301
   174
	assert (set != NULL);
richard@301
   175
krh@248
   176
	pi = zalloc(sizeof *pi);
krh@248
   177
	pi->set = set;
krh@248
   178
krh@248
   179
	if (package) {
krh@248
   180
		pi->index = list_first(&package->properties,
krh@248
   181
				       &set->property_pool);
krh@248
   182
	} else {
krh@248
   183
		pi->property = set->properties.data;
krh@248
   184
		pi->end = set->properties.data + set->properties.size;
krh@248
   185
	}
krh@248
   186
krh@248
   187
	return pi;
krh@248
   188
}
krh@248
   189
krh@269
   190
RAZOR_EXPORT int
krh@248
   191
razor_property_iterator_next(struct razor_property_iterator *pi,
krh@248
   192
			     struct razor_property **property,
krh@248
   193
			     const char **name,
krh@248
   194
			     uint32_t *flags,
krh@248
   195
			     const char **version)
krh@248
   196
{
krh@248
   197
	char *pool;
krh@248
   198
	int valid;
krh@248
   199
	struct razor_property *p, *properties;
krh@248
   200
richard@301
   201
	assert (pi != NULL);
richard@301
   202
krh@248
   203
	if (pi->property) {
krh@248
   204
		p = pi->property++;
krh@248
   205
		valid = p < pi->end;
krh@248
   206
	} else if (pi->index) {
krh@248
   207
		properties = pi->set->properties.data;
krh@248
   208
		p = &properties[pi->index->data];
krh@248
   209
		pi->index = list_next(pi->index);
krh@248
   210
		valid = 1;
krh@248
   211
	} else
krh@248
   212
		valid = 0;
krh@248
   213
krh@248
   214
	if (valid) {
krh@248
   215
		pool = pi->set->string_pool.data;
krh@248
   216
		*property = p;
krh@248
   217
		*name = &pool[p->name];
krh@248
   218
		*flags = p->flags;
krh@248
   219
		*version = &pool[p->version];
krh@248
   220
	} else {
krh@248
   221
		*property = NULL;
krh@248
   222
	}
krh@248
   223
krh@248
   224
	return valid;
krh@248
   225
}
krh@248
   226
krh@269
   227
RAZOR_EXPORT void
krh@248
   228
razor_property_iterator_destroy(struct razor_property_iterator *pi)
krh@248
   229
{
krh@248
   230
	free(pi);
krh@248
   231
}
krh@248
   232
ali@351
   233
RAZOR_EXPORT struct razor_file_iterator *
ali@351
   234
razor_file_iterator_create(struct razor_set *set, struct razor_package *package)
ali@351
   235
{
ali@351
   236
	struct razor_file_iterator *fi;
ali@351
   237
ali@351
   238
	assert (set != NULL);
ali@351
   239
	assert (package != NULL);
ali@351
   240
ali@351
   241
	fi = zalloc(sizeof *fi);
ali@351
   242
	fi->set = set;
ali@351
   243
	fi->index = list_first(&package->files, &set->file_pool);
ali@351
   244
	array_init(&fi->path);
ali@351
   245
ali@351
   246
	return fi;
ali@351
   247
}
ali@351
   248
ali@351
   249
RAZOR_EXPORT int
ali@351
   250
razor_file_iterator_next(struct razor_file_iterator *fi,
ali@351
   251
			 const char **name)
ali@351
   252
{
ali@351
   253
	struct razor_entry *e, *dir, *entries;
ali@351
   254
	char *pool, *s, *f;
ali@351
   255
ali@351
   256
	assert (fi != NULL);
ali@351
   257
ali@351
   258
	if (!fi->index) {
ali@351
   259
		*name = NULL;
ali@351
   260
		return 0;
ali@351
   261
	}
ali@351
   262
ali@351
   263
	entries = (struct razor_entry *) fi->set->files.data;
ali@351
   264
	pool = fi->set->file_string_pool.data;
ali@351
   265
ali@351
   266
	dir = entries;
ali@351
   267
	fi->path.size = 0;
ali@351
   268
	for(;;) {
ali@351
   269
		e = dir;
ali@351
   270
		do {
ali@351
   271
			if (entries + fi->index->data == e) {
ali@351
   272
				f = pool + e->name;
ali@351
   273
				s = array_add(&fi->path, strlen(f) + 1);
ali@351
   274
				strcpy(s, f);
ali@351
   275
				if (fi->path.size == 1) {
ali@351
   276
					array_add(&fi->path, 1);
ali@351
   277
					strcpy(fi->path.data, "/");
ali@351
   278
				}
ali@351
   279
				*name = fi->path.data;
ali@351
   280
				fi->index = list_next(fi->index);
ali@351
   281
				return 1;
ali@351
   282
			}
ali@351
   283
		} while (!((e++)->flags & RAZOR_ENTRY_LAST));
ali@351
   284
		for(e--; e >= dir; e--)
ali@351
   285
			if (e->start && fi->index->data >= e->start)
ali@351
   286
				break;
ali@351
   287
		if (e < dir)
ali@351
   288
			break;
ali@351
   289
		f = pool + e->name;
ali@351
   290
		s = array_add(&fi->path, strlen(f) + 1);
ali@351
   291
		strcpy(s, f);
ali@351
   292
		s += strlen(f);
ali@351
   293
		*s = '/';
ali@351
   294
		dir = entries + e->start;
ali@351
   295
	}
ali@351
   296
ali@351
   297
	printf("file_iterator_next: Failed to find file %d\n",fi->index->data);
ali@351
   298
	*name = NULL;
ali@351
   299
	return 0;
ali@351
   300
}
ali@351
   301
ali@351
   302
RAZOR_EXPORT void razor_file_iterator_destroy(struct razor_file_iterator *fi)
ali@351
   303
{
ali@351
   304
	assert (fi != NULL);
ali@351
   305
ali@351
   306
	array_release(&fi->path);
ali@351
   307
	free(fi);
ali@351
   308
}
ali@351
   309
krh@248
   310
struct razor_package_query {
krh@248
   311
	struct razor_set *set;
krh@248
   312
	char *vector;
krh@248
   313
	int count;
krh@248
   314
};
krh@248
   315
krh@269
   316
RAZOR_EXPORT struct razor_package_query *
krh@248
   317
razor_package_query_create(struct razor_set *set)
krh@248
   318
{
krh@248
   319
	struct razor_package_query *pq;
krh@248
   320
	int count;
krh@248
   321
richard@301
   322
	assert (set != NULL);
richard@301
   323
krh@248
   324
	pq = zalloc(sizeof *pq);
krh@248
   325
	pq->set = set;
krh@248
   326
	count = set->packages.size / sizeof(struct razor_package);
krh@248
   327
	pq->vector = zalloc(count * sizeof(char));
krh@248
   328
krh@248
   329
	return pq;
krh@248
   330
}
krh@248
   331
krh@269
   332
RAZOR_EXPORT void
krh@248
   333
razor_package_query_add_package(struct razor_package_query *pq,
krh@248
   334
				struct razor_package *p)
krh@248
   335
{
krh@248
   336
	struct razor_package *packages;
krh@248
   337
richard@301
   338
	assert (pq != NULL);
richard@301
   339
	assert (p != NULL);
richard@301
   340
krh@248
   341
	packages = pq->set->packages.data;
krh@248
   342
	pq->count += pq->vector[p - packages] ^ 1;
krh@248
   343
	pq->vector[p - packages] = 1;
krh@248
   344
}
krh@248
   345
krh@269
   346
RAZOR_EXPORT void
krh@248
   347
razor_package_query_add_iterator(struct razor_package_query *pq,
krh@248
   348
				 struct razor_package_iterator *pi)
krh@248
   349
{
krh@248
   350
	struct razor_package *packages, *p;
krh@248
   351
richard@301
   352
	assert (pq != NULL);
richard@301
   353
	assert (pi != NULL);
richard@301
   354
krh@248
   355
	packages = pq->set->packages.data;
richard@307
   356
	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) {
krh@248
   357
		pq->count += pq->vector[p - packages] ^ 1;
krh@248
   358
		pq->vector[p - packages] = 1;
krh@248
   359
	}
krh@248
   360
}
krh@248
   361
krh@269
   362
RAZOR_EXPORT struct razor_package_iterator *
krh@248
   363
razor_package_query_finish(struct razor_package_query *pq)
krh@248
   364
{
krh@248
   365
	struct razor_package_iterator *pi;
krh@248
   366
	struct razor_set *set;
krh@248
   367
	struct list *index;
krh@251
   368
	int i, j;
krh@248
   369
richard@301
   370
	assert (pq != NULL);
richard@301
   371
krh@248
   372
	set = pq->set;
krh@251
   373
	if (pq->count > 0)
krh@251
   374
		index = zalloc(pq->count * sizeof *index);
krh@251
   375
	else
krh@251
   376
		index = NULL;
krh@248
   377
krh@267
   378
	for (i = 0, j = 0; j < pq->count; i++) {
krh@248
   379
		if (!pq->vector[i])
krh@248
   380
			continue;
krh@248
   381
krh@248
   382
		index[j].data = i;
krh@248
   383
		if (j == pq->count - 1)
krh@248
   384
			index[j].flags = 0x80;
krh@248
   385
		j++;
krh@248
   386
	}
krh@248
   387
krh@251
   388
	free(pq->vector);
krh@248
   389
	free(pq);
krh@248
   390
krh@248
   391
	pi = razor_package_iterator_create_with_index(set, index);
krh@248
   392
	pi->free_index = 1;
krh@248
   393
krh@248
   394
	return pi;
krh@248
   395
}