librazor/iterator.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Aug 23 11:13:48 2014 +0100 (2014-08-23)
changeset 440 48204dea0b9f
parent 377 5549419824b4
child 442 c4bcba8023a9
permissions -rw-r--r--
Remove INTLLIBS from librazor_la_LIBADD.

This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
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
}