librazor/iterator.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Aug 20 18:57:59 2014 +0100 (2014-08-20)
changeset 439 f28bb31024b4
parent 377 5549419824b4
child 442 c4bcba8023a9
permissions -rw-r--r--
Add secondary text to errors
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
ali@438
    23
#include "config.h"
richard@302
    24
#include <stdarg.h>
krh@248
    25
#include <string.h>
richard@301
    26
#include <assert.h>
richard@301
    27
krh@248
    28
#include "razor-internal.h"
krh@248
    29
#include "razor.h"
krh@248
    30
krh@248
    31
static struct razor_package_iterator *
krh@248
    32
razor_package_iterator_create_with_index(struct razor_set *set,
krh@248
    33
					 struct list *index)
krh@248
    34
{
krh@248
    35
	struct razor_package_iterator *pi;
krh@248
    36
krh@248
    37
	pi = zalloc(sizeof *pi);
krh@248
    38
	pi->set = set;
krh@248
    39
	pi->index = index;
krh@248
    40
krh@248
    41
	return pi;
krh@248
    42
}
krh@248
    43
jbowes@278
    44
static struct razor_package_iterator *
jbowes@278
    45
razor_package_iterator_create_empty(struct razor_set *set)
jbowes@278
    46
{
jbowes@278
    47
	struct razor_package_iterator *pi;
jbowes@278
    48
	return zalloc(sizeof *pi);
jbowes@278
    49
}
jbowes@278
    50
krh@269
    51
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    52
razor_package_iterator_create(struct razor_set *set)
krh@248
    53
{
krh@248
    54
	struct razor_package_iterator *pi;
krh@248
    55
richard@301
    56
	assert (set != NULL);
richard@301
    57
krh@248
    58
	pi = zalloc(sizeof *pi);
krh@248
    59
	pi->set = set;
krh@248
    60
	pi->end = set->packages.data + set->packages.size;
krh@248
    61
	pi->package = set->packages.data;
krh@248
    62
krh@248
    63
	return pi;
krh@248
    64
}
krh@248
    65
krh@269
    66
RAZOR_EXPORT void
krh@248
    67
razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
krh@248
    68
					 struct razor_set *set,
krh@248
    69
					 struct razor_property *property)
krh@248
    70
{
richard@301
    71
	assert (pi != NULL);
richard@301
    72
	assert (set != NULL);
richard@301
    73
	assert (property != NULL);
richard@301
    74
krh@248
    75
	memset(pi, 0, sizeof *pi);
krh@248
    76
	pi->set = set;
krh@248
    77
	pi->index = list_first(&property->packages, &set->package_pool);
krh@248
    78
}
krh@248
    79
krh@269
    80
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    81
razor_package_iterator_create_for_property(struct razor_set *set,
krh@248
    82
					   struct razor_property *property)
krh@248
    83
{
krh@248
    84
	struct list *index;
krh@248
    85
richard@301
    86
	assert (set != NULL);
richard@301
    87
	assert (property != NULL);
richard@301
    88
krh@248
    89
	index = list_first(&property->packages, &set->package_pool);
krh@248
    90
	return razor_package_iterator_create_with_index(set, index);
krh@248
    91
}
krh@248
    92
krh@269
    93
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    94
razor_package_iterator_create_for_file(struct razor_set *set,
krh@248
    95
				       const char *filename)
krh@248
    96
{
krh@248
    97
	struct razor_entry *entry;
krh@248
    98
	struct list *index;
krh@248
    99
richard@301
   100
	assert (set != NULL);
richard@301
   101
	assert (filename != NULL);
richard@301
   102
krh@248
   103
	entry = razor_set_find_entry(set, set->files.data, filename);
krh@248
   104
	if (entry == NULL)
jbowes@278
   105
		return razor_package_iterator_create_empty(set);
krh@248
   106
krh@248
   107
	index = list_first(&entry->packages, &set->package_pool);
krh@248
   108
	return razor_package_iterator_create_with_index(set, index);
krh@248
   109
}
krh@248
   110
richard@302
   111
/**
richard@302
   112
 * razor_package_iterator_next:
richard@302
   113
 * @pi: a %razor_package_iterator
richard@302
   114
 * @package: a %razor_package
richard@302
   115
 *
richard@302
   116
 * Gets the next iteratr along with any vararg data.
krh@308
   117
 * The vararg must be terminated with %RAZOR_DETAIL_LAST.
richard@302
   118
 *
richard@307
   119
 * Example: razor_package_iterator_next (pi, package,
richard@307
   120
 *					 RAZOR_DETAIL_NAME, &name,
richard@307
   121
 *					 RAZOR_DETAIL_LAST);
richard@302
   122
 **/
krh@269
   123
RAZOR_EXPORT int
krh@248
   124
razor_package_iterator_next(struct razor_package_iterator *pi,
richard@302
   125
			    struct razor_package **package, ...)
krh@248
   126
{
richard@302
   127
	va_list args;
krh@248
   128
	int valid;
krh@248
   129
	struct razor_package *p, *packages;
krh@248
   130
richard@301
   131
	assert (pi != NULL);
richard@301
   132
krh@248
   133
	if (pi->package) {
krh@248
   134
		p = pi->package++;
krh@248
   135
		valid = p < pi->end;
krh@248
   136
	} else if (pi->index) {
krh@248
   137
		packages = pi->set->packages.data;
krh@248
   138
		p = &packages[pi->index->data];
krh@248
   139
		pi->index = list_next(pi->index);
krh@248
   140
		valid = 1;
krh@248
   141
	} else
krh@248
   142
		valid = 0;
krh@248
   143
richard@302
   144
	if (valid == 0) {
krh@248
   145
		*package = NULL;
richard@302
   146
		goto out;
krh@248
   147
	}
krh@248
   148
richard@302
   149
	*package = p;
richard@302
   150
richard@302
   151
	va_start(args, NULL);
richard@302
   152
	razor_package_get_details_varg (pi->set, p, args);
richard@302
   153
	va_end (args);
richard@302
   154
out:
krh@248
   155
	return valid;
krh@248
   156
}
krh@248
   157
krh@269
   158
RAZOR_EXPORT void
krh@248
   159
razor_package_iterator_destroy(struct razor_package_iterator *pi)
krh@248
   160
{
richard@301
   161
	assert (pi != NULL);
richard@301
   162
krh@248
   163
	if (pi->free_index)
krh@248
   164
		free(pi->index);
krh@248
   165
krh@248
   166
	free(pi);
krh@248
   167
}
krh@248
   168
krh@269
   169
RAZOR_EXPORT struct razor_property_iterator *
krh@248
   170
razor_property_iterator_create(struct razor_set *set,
krh@248
   171
			       struct razor_package *package)
krh@248
   172
{
krh@248
   173
	struct razor_property_iterator *pi;
krh@248
   174
richard@301
   175
	assert (set != NULL);
richard@301
   176
krh@248
   177
	pi = zalloc(sizeof *pi);
krh@248
   178
	pi->set = set;
krh@248
   179
krh@248
   180
	if (package) {
krh@248
   181
		pi->index = list_first(&package->properties,
krh@248
   182
				       &set->property_pool);
krh@248
   183
	} else {
krh@248
   184
		pi->property = set->properties.data;
krh@248
   185
		pi->end = set->properties.data + set->properties.size;
krh@248
   186
	}
krh@248
   187
krh@248
   188
	return pi;
krh@248
   189
}
krh@248
   190
krh@269
   191
RAZOR_EXPORT int
krh@248
   192
razor_property_iterator_next(struct razor_property_iterator *pi,
krh@248
   193
			     struct razor_property **property,
krh@248
   194
			     const char **name,
krh@248
   195
			     uint32_t *flags,
krh@248
   196
			     const char **version)
krh@248
   197
{
krh@248
   198
	char *pool;
krh@248
   199
	int valid;
krh@248
   200
	struct razor_property *p, *properties;
krh@248
   201
richard@301
   202
	assert (pi != NULL);
richard@301
   203
krh@248
   204
	if (pi->property) {
krh@248
   205
		p = pi->property++;
krh@248
   206
		valid = p < pi->end;
krh@248
   207
	} else if (pi->index) {
krh@248
   208
		properties = pi->set->properties.data;
krh@248
   209
		p = &properties[pi->index->data];
krh@248
   210
		pi->index = list_next(pi->index);
krh@248
   211
		valid = 1;
krh@248
   212
	} else
krh@248
   213
		valid = 0;
krh@248
   214
krh@248
   215
	if (valid) {
krh@248
   216
		pool = pi->set->string_pool.data;
krh@248
   217
		*property = p;
krh@248
   218
		*name = &pool[p->name];
krh@248
   219
		*flags = p->flags;
krh@248
   220
		*version = &pool[p->version];
krh@248
   221
	} else {
krh@248
   222
		*property = NULL;
krh@248
   223
	}
krh@248
   224
krh@248
   225
	return valid;
krh@248
   226
}
krh@248
   227
krh@269
   228
RAZOR_EXPORT void
krh@248
   229
razor_property_iterator_destroy(struct razor_property_iterator *pi)
krh@248
   230
{
krh@248
   231
	free(pi);
krh@248
   232
}
krh@248
   233
ali@351
   234
RAZOR_EXPORT struct razor_file_iterator *
ali@377
   235
razor_file_iterator_create(struct razor_set *set, struct razor_package *package,
ali@377
   236
			   int post_order)
ali@351
   237
{
ali@351
   238
	struct razor_file_iterator *fi;
ali@351
   239
ali@351
   240
	assert (set != NULL);
ali@351
   241
	assert (package != NULL);
ali@351
   242
ali@351
   243
	fi = zalloc(sizeof *fi);
ali@351
   244
	fi->set = set;
ali@377
   245
	fi->post_order = post_order;
ali@377
   246
	if (post_order)
ali@377
   247
		fi->index = list_last(&package->files, &set->file_pool);
ali@377
   248
	else
ali@377
   249
		fi->index = list_first(&package->files, &set->file_pool);
ali@351
   250
	array_init(&fi->path);
ali@351
   251
ali@351
   252
	return fi;
ali@351
   253
}
ali@351
   254
ali@351
   255
RAZOR_EXPORT int
ali@351
   256
razor_file_iterator_next(struct razor_file_iterator *fi,
ali@351
   257
			 const char **name)
ali@351
   258
{
ali@351
   259
	struct razor_entry *e, *dir, *entries;
ali@351
   260
	char *pool, *s, *f;
ali@351
   261
ali@351
   262
	assert (fi != NULL);
ali@351
   263
ali@351
   264
	if (!fi->index) {
ali@351
   265
		*name = NULL;
ali@351
   266
		return 0;
ali@351
   267
	}
ali@351
   268
ali@351
   269
	entries = (struct razor_entry *) fi->set->files.data;
ali@351
   270
	pool = fi->set->file_string_pool.data;
ali@351
   271
ali@351
   272
	dir = entries;
ali@351
   273
	fi->path.size = 0;
ali@351
   274
	for(;;) {
ali@351
   275
		e = dir;
ali@351
   276
		do {
ali@351
   277
			if (entries + fi->index->data == e) {
ali@351
   278
				f = pool + e->name;
ali@351
   279
				s = array_add(&fi->path, strlen(f) + 1);
ali@351
   280
				strcpy(s, f);
ali@351
   281
				if (fi->path.size == 1) {
ali@351
   282
					array_add(&fi->path, 1);
ali@351
   283
					strcpy(fi->path.data, "/");
ali@351
   284
				}
ali@351
   285
				*name = fi->path.data;
ali@377
   286
				if (fi->post_order)
ali@377
   287
					fi->index = list_prev(fi->index);
ali@377
   288
				else
ali@377
   289
					fi->index = list_next(fi->index);
ali@351
   290
				return 1;
ali@351
   291
			}
ali@351
   292
		} while (!((e++)->flags & RAZOR_ENTRY_LAST));
ali@351
   293
		for(e--; e >= dir; e--)
ali@351
   294
			if (e->start && fi->index->data >= e->start)
ali@351
   295
				break;
ali@351
   296
		if (e < dir)
ali@351
   297
			break;
ali@351
   298
		f = pool + e->name;
ali@351
   299
		s = array_add(&fi->path, strlen(f) + 1);
ali@351
   300
		strcpy(s, f);
ali@351
   301
		s += strlen(f);
ali@351
   302
		*s = '/';
ali@351
   303
		dir = entries + e->start;
ali@351
   304
	}
ali@351
   305
ali@351
   306
	printf("file_iterator_next: Failed to find file %d\n",fi->index->data);
ali@351
   307
	*name = NULL;
ali@351
   308
	return 0;
ali@351
   309
}
ali@351
   310
ali@351
   311
RAZOR_EXPORT void razor_file_iterator_destroy(struct razor_file_iterator *fi)
ali@351
   312
{
ali@351
   313
	assert (fi != NULL);
ali@351
   314
ali@351
   315
	array_release(&fi->path);
ali@351
   316
	free(fi);
ali@351
   317
}
ali@351
   318
krh@248
   319
struct razor_package_query {
krh@248
   320
	struct razor_set *set;
krh@248
   321
	char *vector;
krh@248
   322
	int count;
krh@248
   323
};
krh@248
   324
krh@269
   325
RAZOR_EXPORT struct razor_package_query *
krh@248
   326
razor_package_query_create(struct razor_set *set)
krh@248
   327
{
krh@248
   328
	struct razor_package_query *pq;
krh@248
   329
	int count;
krh@248
   330
richard@301
   331
	assert (set != NULL);
richard@301
   332
krh@248
   333
	pq = zalloc(sizeof *pq);
krh@248
   334
	pq->set = set;
krh@248
   335
	count = set->packages.size / sizeof(struct razor_package);
krh@248
   336
	pq->vector = zalloc(count * sizeof(char));
krh@248
   337
krh@248
   338
	return pq;
krh@248
   339
}
krh@248
   340
krh@269
   341
RAZOR_EXPORT void
krh@248
   342
razor_package_query_add_package(struct razor_package_query *pq,
krh@248
   343
				struct razor_package *p)
krh@248
   344
{
krh@248
   345
	struct razor_package *packages;
krh@248
   346
richard@301
   347
	assert (pq != NULL);
richard@301
   348
	assert (p != NULL);
richard@301
   349
krh@248
   350
	packages = pq->set->packages.data;
krh@248
   351
	pq->count += pq->vector[p - packages] ^ 1;
krh@248
   352
	pq->vector[p - packages] = 1;
krh@248
   353
}
krh@248
   354
krh@269
   355
RAZOR_EXPORT void
krh@248
   356
razor_package_query_add_iterator(struct razor_package_query *pq,
krh@248
   357
				 struct razor_package_iterator *pi)
krh@248
   358
{
krh@248
   359
	struct razor_package *packages, *p;
krh@248
   360
richard@301
   361
	assert (pq != NULL);
richard@301
   362
	assert (pi != NULL);
richard@301
   363
krh@248
   364
	packages = pq->set->packages.data;
richard@307
   365
	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) {
krh@248
   366
		pq->count += pq->vector[p - packages] ^ 1;
krh@248
   367
		pq->vector[p - packages] = 1;
krh@248
   368
	}
krh@248
   369
}
krh@248
   370
krh@269
   371
RAZOR_EXPORT struct razor_package_iterator *
krh@248
   372
razor_package_query_finish(struct razor_package_query *pq)
krh@248
   373
{
krh@248
   374
	struct razor_package_iterator *pi;
krh@248
   375
	struct razor_set *set;
krh@248
   376
	struct list *index;
krh@251
   377
	int i, j;
krh@248
   378
richard@301
   379
	assert (pq != NULL);
richard@301
   380
krh@248
   381
	set = pq->set;
krh@251
   382
	if (pq->count > 0)
krh@251
   383
		index = zalloc(pq->count * sizeof *index);
krh@251
   384
	else
krh@251
   385
		index = NULL;
krh@248
   386
krh@267
   387
	for (i = 0, j = 0; j < pq->count; i++) {
krh@248
   388
		if (!pq->vector[i])
krh@248
   389
			continue;
krh@248
   390
krh@248
   391
		index[j].data = i;
krh@248
   392
		if (j == pq->count - 1)
krh@248
   393
			index[j].flags = 0x80;
krh@248
   394
		j++;
krh@248
   395
	}
krh@248
   396
krh@251
   397
	free(pq->vector);
krh@248
   398
	free(pq);
krh@248
   399
krh@248
   400
	pi = razor_package_iterator_create_with_index(set, index);
krh@248
   401
	pi->free_index = 1;
krh@248
   402
krh@248
   403
	return pi;
krh@248
   404
}