librazor/iterator.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Jan 12 16:37:55 2009 +0000 (2009-01-12)
changeset 344 1b54aa2137d3
parent 307 95b6bcadd6c4
child 351 48b0adfe3059
permissions -rw-r--r--
Generate razor.pc in line with details determined during config
krh@248
     1
/*
krh@248
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
krh@248
     3
 * Copyright (C) 2008  Red Hat, Inc
krh@248
     4
 *
krh@248
     5
 * This program is free software; you can redistribute it and/or modify
krh@248
     6
 * it under the terms of the GNU General Public License as published by
krh@248
     7
 * the Free Software Foundation; either version 2 of the License, or
krh@248
     8
 * (at your option) any later version.
krh@248
     9
 *
krh@248
    10
 * This program is distributed in the hope that it will be useful,
krh@248
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
krh@248
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
krh@248
    13
 * GNU General Public License for more details.
krh@248
    14
 *
krh@248
    15
 * You should have received a copy of the GNU General Public License along
krh@248
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
krh@248
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
krh@248
    18
 */
krh@248
    19
krh@248
    20
#define _GNU_SOURCE
krh@248
    21
richard@302
    22
#include <stdarg.h>
krh@248
    23
#include <string.h>
richard@301
    24
#include <assert.h>
richard@301
    25
krh@248
    26
#include "razor-internal.h"
krh@248
    27
#include "razor.h"
krh@248
    28
krh@248
    29
static struct razor_package_iterator *
krh@248
    30
razor_package_iterator_create_with_index(struct razor_set *set,
krh@248
    31
					 struct list *index)
krh@248
    32
{
krh@248
    33
	struct razor_package_iterator *pi;
krh@248
    34
krh@248
    35
	pi = zalloc(sizeof *pi);
krh@248
    36
	pi->set = set;
krh@248
    37
	pi->index = index;
krh@248
    38
krh@248
    39
	return pi;
krh@248
    40
}
krh@248
    41
jbowes@278
    42
static struct razor_package_iterator *
jbowes@278
    43
razor_package_iterator_create_empty(struct razor_set *set)
jbowes@278
    44
{
jbowes@278
    45
	struct razor_package_iterator *pi;
jbowes@278
    46
	return zalloc(sizeof *pi);
jbowes@278
    47
}
jbowes@278
    48
krh@269
    49
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    50
razor_package_iterator_create(struct razor_set *set)
krh@248
    51
{
krh@248
    52
	struct razor_package_iterator *pi;
krh@248
    53
richard@301
    54
	assert (set != NULL);
richard@301
    55
krh@248
    56
	pi = zalloc(sizeof *pi);
krh@248
    57
	pi->set = set;
krh@248
    58
	pi->end = set->packages.data + set->packages.size;
krh@248
    59
	pi->package = set->packages.data;
krh@248
    60
krh@248
    61
	return pi;
krh@248
    62
}
krh@248
    63
krh@269
    64
RAZOR_EXPORT void
krh@248
    65
razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
krh@248
    66
					 struct razor_set *set,
krh@248
    67
					 struct razor_property *property)
krh@248
    68
{
richard@301
    69
	assert (pi != NULL);
richard@301
    70
	assert (set != NULL);
richard@301
    71
	assert (property != NULL);
richard@301
    72
krh@248
    73
	memset(pi, 0, sizeof *pi);
krh@248
    74
	pi->set = set;
krh@248
    75
	pi->index = list_first(&property->packages, &set->package_pool);
krh@248
    76
}
krh@248
    77
krh@269
    78
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    79
razor_package_iterator_create_for_property(struct razor_set *set,
krh@248
    80
					   struct razor_property *property)
krh@248
    81
{
krh@248
    82
	struct list *index;
krh@248
    83
richard@301
    84
	assert (set != NULL);
richard@301
    85
	assert (property != NULL);
richard@301
    86
krh@248
    87
	index = list_first(&property->packages, &set->package_pool);
krh@248
    88
	return razor_package_iterator_create_with_index(set, index);
krh@248
    89
}
krh@248
    90
krh@269
    91
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    92
razor_package_iterator_create_for_file(struct razor_set *set,
krh@248
    93
				       const char *filename)
krh@248
    94
{
krh@248
    95
	struct razor_entry *entry;
krh@248
    96
	struct list *index;
krh@248
    97
richard@301
    98
	assert (set != NULL);
richard@301
    99
	assert (filename != NULL);
richard@301
   100
krh@248
   101
	entry = razor_set_find_entry(set, set->files.data, filename);
krh@248
   102
	if (entry == NULL)
jbowes@278
   103
		return razor_package_iterator_create_empty(set);
krh@248
   104
krh@248
   105
	index = list_first(&entry->packages, &set->package_pool);
krh@248
   106
	return razor_package_iterator_create_with_index(set, index);
krh@248
   107
}
krh@248
   108
richard@302
   109
/**
richard@302
   110
 * razor_package_iterator_next:
richard@302
   111
 * @pi: a %razor_package_iterator
richard@302
   112
 * @package: a %razor_package
richard@302
   113
 *
richard@302
   114
 * Gets the next iteratr along with any vararg data.
krh@308
   115
 * The vararg must be terminated with %RAZOR_DETAIL_LAST.
richard@302
   116
 *
richard@307
   117
 * Example: razor_package_iterator_next (pi, package,
richard@307
   118
 *					 RAZOR_DETAIL_NAME, &name,
richard@307
   119
 *					 RAZOR_DETAIL_LAST);
richard@302
   120
 **/
krh@269
   121
RAZOR_EXPORT int
krh@248
   122
razor_package_iterator_next(struct razor_package_iterator *pi,
richard@302
   123
			    struct razor_package **package, ...)
krh@248
   124
{
richard@302
   125
	va_list args;
krh@248
   126
	int valid;
krh@248
   127
	struct razor_package *p, *packages;
krh@248
   128
richard@301
   129
	assert (pi != NULL);
richard@301
   130
krh@248
   131
	if (pi->package) {
krh@248
   132
		p = pi->package++;
krh@248
   133
		valid = p < pi->end;
krh@248
   134
	} else if (pi->index) {
krh@248
   135
		packages = pi->set->packages.data;
krh@248
   136
		p = &packages[pi->index->data];
krh@248
   137
		pi->index = list_next(pi->index);
krh@248
   138
		valid = 1;
krh@248
   139
	} else
krh@248
   140
		valid = 0;
krh@248
   141
richard@302
   142
	if (valid == 0) {
krh@248
   143
		*package = NULL;
richard@302
   144
		goto out;
krh@248
   145
	}
krh@248
   146
richard@302
   147
	*package = p;
richard@302
   148
richard@302
   149
	va_start(args, NULL);
richard@302
   150
	razor_package_get_details_varg (pi->set, p, args);
richard@302
   151
	va_end (args);
richard@302
   152
out:
krh@248
   153
	return valid;
krh@248
   154
}
krh@248
   155
krh@269
   156
RAZOR_EXPORT void
krh@248
   157
razor_package_iterator_destroy(struct razor_package_iterator *pi)
krh@248
   158
{
richard@301
   159
	assert (pi != NULL);
richard@301
   160
krh@248
   161
	if (pi->free_index)
krh@248
   162
		free(pi->index);
krh@248
   163
krh@248
   164
	free(pi);
krh@248
   165
}
krh@248
   166
krh@269
   167
RAZOR_EXPORT struct razor_property_iterator *
krh@248
   168
razor_property_iterator_create(struct razor_set *set,
krh@248
   169
			       struct razor_package *package)
krh@248
   170
{
krh@248
   171
	struct razor_property_iterator *pi;
krh@248
   172
richard@301
   173
	assert (set != NULL);
richard@301
   174
krh@248
   175
	pi = zalloc(sizeof *pi);
krh@248
   176
	pi->set = set;
krh@248
   177
krh@248
   178
	if (package) {
krh@248
   179
		pi->index = list_first(&package->properties,
krh@248
   180
				       &set->property_pool);
krh@248
   181
	} else {
krh@248
   182
		pi->property = set->properties.data;
krh@248
   183
		pi->end = set->properties.data + set->properties.size;
krh@248
   184
	}
krh@248
   185
krh@248
   186
	return pi;
krh@248
   187
}
krh@248
   188
krh@269
   189
RAZOR_EXPORT int
krh@248
   190
razor_property_iterator_next(struct razor_property_iterator *pi,
krh@248
   191
			     struct razor_property **property,
krh@248
   192
			     const char **name,
krh@248
   193
			     uint32_t *flags,
krh@248
   194
			     const char **version)
krh@248
   195
{
krh@248
   196
	char *pool;
krh@248
   197
	int valid;
krh@248
   198
	struct razor_property *p, *properties;
krh@248
   199
richard@301
   200
	assert (pi != NULL);
richard@301
   201
krh@248
   202
	if (pi->property) {
krh@248
   203
		p = pi->property++;
krh@248
   204
		valid = p < pi->end;
krh@248
   205
	} else if (pi->index) {
krh@248
   206
		properties = pi->set->properties.data;
krh@248
   207
		p = &properties[pi->index->data];
krh@248
   208
		pi->index = list_next(pi->index);
krh@248
   209
		valid = 1;
krh@248
   210
	} else
krh@248
   211
		valid = 0;
krh@248
   212
krh@248
   213
	if (valid) {
krh@248
   214
		pool = pi->set->string_pool.data;
krh@248
   215
		*property = p;
krh@248
   216
		*name = &pool[p->name];
krh@248
   217
		*flags = p->flags;
krh@248
   218
		*version = &pool[p->version];
krh@248
   219
	} else {
krh@248
   220
		*property = NULL;
krh@248
   221
	}
krh@248
   222
krh@248
   223
	return valid;
krh@248
   224
}
krh@248
   225
krh@269
   226
RAZOR_EXPORT void
krh@248
   227
razor_property_iterator_destroy(struct razor_property_iterator *pi)
krh@248
   228
{
krh@248
   229
	free(pi);
krh@248
   230
}
krh@248
   231
krh@248
   232
struct razor_package_query {
krh@248
   233
	struct razor_set *set;
krh@248
   234
	char *vector;
krh@248
   235
	int count;
krh@248
   236
};
krh@248
   237
krh@269
   238
RAZOR_EXPORT struct razor_package_query *
krh@248
   239
razor_package_query_create(struct razor_set *set)
krh@248
   240
{
krh@248
   241
	struct razor_package_query *pq;
krh@248
   242
	int count;
krh@248
   243
richard@301
   244
	assert (set != NULL);
richard@301
   245
krh@248
   246
	pq = zalloc(sizeof *pq);
krh@248
   247
	pq->set = set;
krh@248
   248
	count = set->packages.size / sizeof(struct razor_package);
krh@248
   249
	pq->vector = zalloc(count * sizeof(char));
krh@248
   250
krh@248
   251
	return pq;
krh@248
   252
}
krh@248
   253
krh@269
   254
RAZOR_EXPORT void
krh@248
   255
razor_package_query_add_package(struct razor_package_query *pq,
krh@248
   256
				struct razor_package *p)
krh@248
   257
{
krh@248
   258
	struct razor_package *packages;
krh@248
   259
richard@301
   260
	assert (pq != NULL);
richard@301
   261
	assert (p != NULL);
richard@301
   262
krh@248
   263
	packages = pq->set->packages.data;
krh@248
   264
	pq->count += pq->vector[p - packages] ^ 1;
krh@248
   265
	pq->vector[p - packages] = 1;
krh@248
   266
}
krh@248
   267
krh@269
   268
RAZOR_EXPORT void
krh@248
   269
razor_package_query_add_iterator(struct razor_package_query *pq,
krh@248
   270
				 struct razor_package_iterator *pi)
krh@248
   271
{
krh@248
   272
	struct razor_package *packages, *p;
krh@248
   273
richard@301
   274
	assert (pq != NULL);
richard@301
   275
	assert (pi != NULL);
richard@301
   276
krh@248
   277
	packages = pq->set->packages.data;
richard@307
   278
	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) {
krh@248
   279
		pq->count += pq->vector[p - packages] ^ 1;
krh@248
   280
		pq->vector[p - packages] = 1;
krh@248
   281
	}
krh@248
   282
}
krh@248
   283
krh@269
   284
RAZOR_EXPORT struct razor_package_iterator *
krh@248
   285
razor_package_query_finish(struct razor_package_query *pq)
krh@248
   286
{
krh@248
   287
	struct razor_package_iterator *pi;
krh@248
   288
	struct razor_set *set;
krh@248
   289
	struct list *index;
krh@251
   290
	int i, j;
krh@248
   291
richard@301
   292
	assert (pq != NULL);
richard@301
   293
krh@248
   294
	set = pq->set;
krh@251
   295
	if (pq->count > 0)
krh@251
   296
		index = zalloc(pq->count * sizeof *index);
krh@251
   297
	else
krh@251
   298
		index = NULL;
krh@248
   299
krh@267
   300
	for (i = 0, j = 0; j < pq->count; i++) {
krh@248
   301
		if (!pq->vector[i])
krh@248
   302
			continue;
krh@248
   303
krh@248
   304
		index[j].data = i;
krh@248
   305
		if (j == pq->count - 1)
krh@248
   306
			index[j].flags = 0x80;
krh@248
   307
		j++;
krh@248
   308
	}
krh@248
   309
krh@251
   310
	free(pq->vector);
krh@248
   311
	free(pq);
krh@248
   312
krh@248
   313
	pi = razor_package_iterator_create_with_index(set, index);
krh@248
   314
	pi->free_index = 1;
krh@248
   315
krh@248
   316
	return pi;
krh@248
   317
}