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