Blame library/seq.c

Packit Service 6d40f9
/*
Packit Service 6d40f9
 * adcli
Packit Service 6d40f9
 *
Packit Service 6d40f9
 * Copyright (C) 2013 Red Hat Inc.
Packit Service 6d40f9
 *
Packit Service 6d40f9
 * This program is free software; you can redistribute it and/or modify
Packit Service 6d40f9
 * it under the terms of the GNU Lesser General Public License as
Packit Service 6d40f9
 * published by the Free Software Foundation; either version 2.1 of
Packit Service 6d40f9
 * the License, or (at your option) any later version.
Packit Service 6d40f9
 *
Packit Service 6d40f9
 * This program is distributed in the hope that it will be useful, but
Packit Service 6d40f9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 6d40f9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 6d40f9
 * Lesser General Public License for more details.
Packit Service 6d40f9
 *
Packit Service 6d40f9
 * You should have received a copy of the GNU Lesser General Public
Packit Service 6d40f9
 * License along with this program; if not, write to the Free Software
Packit Service 6d40f9
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
Packit Service 6d40f9
 * MA 02110-1301 USA
Packit Service 6d40f9
 *
Packit Service 6d40f9
 * Author: Stef Walter <stefw@redhat.com>
Packit Service 6d40f9
 */
Packit Service 6d40f9
Packit Service 6d40f9
#include "config.h"
Packit Service 6d40f9
Packit Service 6d40f9
#include "seq.h"
Packit Service 6d40f9
Packit Service 6d40f9
#include <assert.h>
Packit Service 6d40f9
#include <stdlib.h>
Packit Service 6d40f9
#include <string.h>
Packit Service 6d40f9
Packit Service 6d40f9
/* For detecting clang features */
Packit Service 6d40f9
#ifndef __has_feature
Packit Service 6d40f9
#define __has_feature(x) 0
Packit Service 6d40f9
#endif
Packit Service 6d40f9
Packit Service 6d40f9
#ifndef CLANG_ANALYZER_NORETURN
Packit Service 6d40f9
#if __has_feature(attribute_analyzer_noreturn)
Packit Service 6d40f9
#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
Packit Service 6d40f9
#else
Packit Service 6d40f9
#define CLANG_ANALYZER_NORETURN
Packit Service 6d40f9
#endif
Packit Service 6d40f9
#endif
Packit Service 6d40f9
Packit Service 6d40f9
/* to make coverage simple */
Packit Service 6d40f9
#define bail_on_null(v) do { if ((v) == NULL) return bail_null (); } while (0)
Packit Service 6d40f9
Packit Service 6d40f9
static void *
Packit Service 6d40f9
bail_null (void)
Packit Service 6d40f9
CLANG_ANALYZER_NORETURN;
Packit Service 6d40f9
Packit Service 6d40f9
static void *
Packit Service 6d40f9
bail_null (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	return NULL;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static int
Packit Service 6d40f9
alloc_size (int num)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int n = num ? 1 : 0;
Packit Service 6d40f9
	while (n < num && n > 0)
Packit Service 6d40f9
		n <<= 1;
Packit Service 6d40f9
	return n;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
int
Packit Service 6d40f9
seq_count (seq_voidp sequence)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int count;
Packit Service 6d40f9
	for (count = 0; seq && seq[count]; count++);
Packit Service 6d40f9
	return count;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void **
Packit Service 6d40f9
guarantee_one_more (void **seq,
Packit Service 6d40f9
                    int len)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int alloc;
Packit Service 6d40f9
Packit Service 6d40f9
	alloc = alloc_size (len + 1);
Packit Service 6d40f9
	assert (alloc != 0);
Packit Service 6d40f9
Packit Service 6d40f9
	if (len + 2 > alloc) {
Packit Service 6d40f9
		assert (alloc != 0);
Packit Service 6d40f9
		seq = realloc (seq, alloc * 2 * sizeof (void *));
Packit Service 6d40f9
	}
Packit Service 6d40f9
Packit Service 6d40f9
	return seq;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void *
Packit Service 6d40f9
seq_push (seq_voidp sequence,
Packit Service 6d40f9
          int *length,
Packit Service 6d40f9
          void *value)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
	assert (value != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service 6d40f9
	seq = guarantee_one_more (seq, len);
Packit Service 6d40f9
	if (seq) {
Packit Service 6d40f9
		seq[len++] = value;
Packit Service 6d40f9
		seq[len] = NULL;
Packit Service 6d40f9
		*length = len;
Packit Service 6d40f9
	}
Packit Service 6d40f9
	return seq;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static int
Packit Service c76c4a
linear_search (void **seq,
Packit Service c76c4a
               int low,
Packit Service c76c4a
               int high,
Packit Service c76c4a
               void *match,
Packit Service c76c4a
               seq_compar compar)
Packit Service c76c4a
{
Packit Service c76c4a
	int at;
Packit Service c76c4a
Packit Service c76c4a
	for (at = low; at < high; at++) {
Packit Service c76c4a
		if (compar (match, seq[at]) == 0) {
Packit Service c76c4a
			break;
Packit Service c76c4a
		}
Packit Service c76c4a
	}
Packit Service c76c4a
Packit Service c76c4a
	return at;
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service c76c4a
static int
Packit Service 6d40f9
binary_search (void **seq,
Packit Service 6d40f9
               int low,
Packit Service 6d40f9
               int high,
Packit Service 6d40f9
               void *match,
Packit Service 6d40f9
               seq_compar compar)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int res;
Packit Service 6d40f9
	int mid;
Packit Service 6d40f9
Packit Service 6d40f9
	if (low == high)
Packit Service 6d40f9
		return low;
Packit Service 6d40f9
Packit Service 6d40f9
	mid = low + ((high - low) / 2);
Packit Service 6d40f9
	res = compar (match, seq[mid]);
Packit Service 6d40f9
	if (res > 0)
Packit Service 6d40f9
		return binary_search (seq, mid + 1, high, match, compar);
Packit Service 6d40f9
	else if (res < 0)
Packit Service 6d40f9
		return binary_search (seq, low, mid, match, compar);
Packit Service 6d40f9
Packit Service 6d40f9
	return mid;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void *
Packit Service 6d40f9
seq_insert (seq_voidp sequence,
Packit Service 6d40f9
            int *length,
Packit Service 6d40f9
            void *value,
Packit Service 6d40f9
            seq_compar compar,
Packit Service 6d40f9
            seq_destroy destroy)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int at;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
	assert (compar != NULL);
Packit Service 6d40f9
	assert (value != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service 6d40f9
	at = binary_search (seq, 0, len, value, compar);
Packit Service 6d40f9
Packit Service 6d40f9
	/* We already have a matching value */
Packit Service 6d40f9
	if (at < len && compar (value, seq[at]) == 0) {
Packit Service 6d40f9
		if (destroy != NULL)
Packit Service 6d40f9
			destroy (seq[at]);
Packit Service 6d40f9
Packit Service 6d40f9
	/* Need to insert a value */
Packit Service 6d40f9
	} else {
Packit Service 6d40f9
		seq = guarantee_one_more (seq, len);
Packit Service 6d40f9
		bail_on_null (seq);
Packit Service 6d40f9
		memmove (seq + at + 1, seq + at, (len - at) * sizeof (void *));
Packit Service 6d40f9
		len++;
Packit Service 6d40f9
		seq[len] = NULL;
Packit Service 6d40f9
	}
Packit Service 6d40f9
Packit Service 6d40f9
	seq[at] = value;
Packit Service 6d40f9
	*length = len;
Packit Service 6d40f9
	return seq;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service c76c4a
static void
Packit Service c76c4a
seq_remove_int (seq_voidp sequence,
Packit Service c76c4a
                int *length,
Packit Service c76c4a
                void *match,
Packit Service c76c4a
                seq_search search,
Packit Service c76c4a
                seq_compar compar,
Packit Service c76c4a
                seq_destroy destroy)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int at;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
	assert (compar != NULL);
Packit Service 6d40f9
	assert (match != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service c76c4a
	at = search (seq, 0, len, match, compar);
Packit Service 6d40f9
Packit Service 6d40f9
	/* We have a matching value */
Packit Service 6d40f9
	if (at < len && compar (match, seq[at]) == 0) {
Packit Service 6d40f9
		if (destroy != NULL)
Packit Service 6d40f9
			destroy (seq[at]);
Packit Service 6d40f9
		memmove (seq + at, seq + at + 1, (len - at) * sizeof (void *));
Packit Service 6d40f9
		len--;
Packit Service 6d40f9
		seq[len] = NULL;
Packit Service 6d40f9
	}
Packit Service 6d40f9
Packit Service 6d40f9
	*length = len;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void
Packit Service c76c4a
seq_remove (seq_voidp sequence,
Packit Service c76c4a
            int *length,
Packit Service c76c4a
            void *match,
Packit Service c76c4a
            seq_compar compar,
Packit Service c76c4a
            seq_destroy destroy)
Packit Service c76c4a
{
Packit Service c76c4a
	return seq_remove_int (sequence, length, match, binary_search, compar, destroy);
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service c76c4a
void
Packit Service c76c4a
seq_remove_unsorted (seq_voidp sequence,
Packit Service c76c4a
                     int *length,
Packit Service c76c4a
                     void *match,
Packit Service c76c4a
                     seq_compar compar,
Packit Service c76c4a
                     seq_destroy destroy)
Packit Service c76c4a
{
Packit Service c76c4a
	return seq_remove_int (sequence, length, match, linear_search, compar, destroy);
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service c76c4a
void
Packit Service 6d40f9
seq_filter (seq_voidp sequence,
Packit Service 6d40f9
            int *length,
Packit Service 6d40f9
            void *match,
Packit Service 6d40f9
            seq_compar compar,
Packit Service 6d40f9
            seq_destroy destroy)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
	int in, out;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
	assert (compar != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	if (!sequence)
Packit Service 6d40f9
		return;
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service 6d40f9
Packit Service 6d40f9
	for (in = 0, out = 0; in < len; in++) {
Packit Service 6d40f9
		if (compar (match, seq[in]) == 0) {
Packit Service 6d40f9
			seq[out++] = seq[in];
Packit Service 6d40f9
		} else {
Packit Service 6d40f9
			if (destroy)
Packit Service 6d40f9
				destroy (seq[in]);
Packit Service 6d40f9
		}
Packit Service 6d40f9
	}
Packit Service 6d40f9
Packit Service 6d40f9
	seq[out] = NULL;
Packit Service 6d40f9
	*length = out;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void *
Packit Service 6d40f9
seq_lookup (seq_voidp sequence,
Packit Service 6d40f9
            int *length,
Packit Service 6d40f9
            void *match,
Packit Service 6d40f9
            seq_compar compar)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int at;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
	assert (compar != NULL);
Packit Service 6d40f9
	assert (match != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service 6d40f9
	at = binary_search (seq, 0, len, match, compar);
Packit Service 6d40f9
Packit Service 6d40f9
	/* We have a matching value */
Packit Service 6d40f9
	if (at < len && compar (match, seq[at]) == 0)
Packit Service 6d40f9
		return seq[at];
Packit Service 6d40f9
Packit Service 6d40f9
	return NULL;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void *
Packit Service 6d40f9
seq_dup (seq_voidp sequence,
Packit Service 6d40f9
         int *length,
Packit Service 6d40f9
         seq_copy copy)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	void **copied;
Packit Service 6d40f9
	int alloc;
Packit Service 6d40f9
	int len;
Packit Service 6d40f9
	int at;
Packit Service 6d40f9
Packit Service 6d40f9
	assert (length != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	len = *length;
Packit Service 6d40f9
	alloc = alloc_size (len + 1);
Packit Service 6d40f9
	assert (alloc != 0);
Packit Service 6d40f9
Packit Service 6d40f9
	copied = calloc (alloc, sizeof (void *));
Packit Service 6d40f9
	bail_on_null (copied);
Packit Service 6d40f9
Packit Service 6d40f9
	for (at = 0; at < len; at++) {
Packit Service 6d40f9
		if (copy == NULL) {
Packit Service 6d40f9
			copied[at] = seq[at];
Packit Service 6d40f9
		} else {
Packit Service 6d40f9
			copied[at] = copy (seq[at]);
Packit Service 6d40f9
			bail_on_null (copied[at]);
Packit Service 6d40f9
		}
Packit Service 6d40f9
	}
Packit Service 6d40f9
Packit Service 6d40f9
	copied[len] = NULL;
Packit Service 6d40f9
	return copied;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
void
Packit Service 6d40f9
seq_free (seq_voidp sequence,
Packit Service 6d40f9
          seq_destroy destroy)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = sequence;
Packit Service 6d40f9
	int at;
Packit Service 6d40f9
Packit Service 6d40f9
	for (at = 0; destroy && seq && seq[at] != NULL; at++)
Packit Service 6d40f9
		(destroy) (seq[at]);
Packit Service 6d40f9
Packit Service 6d40f9
	free (seq);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
#ifdef SEQ_TESTS
Packit Service 6d40f9
Packit Service 6d40f9
#include "test.h"
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_push (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_push (seq, &len, "5");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "4");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "3");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "2");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "1");
Packit Service 6d40f9
Packit Service 6d40f9
	assert (seq != NULL);
Packit Service 6d40f9
	assert_str_eq (seq[0], "5");
Packit Service 6d40f9
	assert_str_eq (seq[1], "4");
Packit Service 6d40f9
	assert_str_eq (seq[2], "3");
Packit Service 6d40f9
	assert_str_eq (seq[3], "2");
Packit Service 6d40f9
	assert_str_eq (seq[4], "1");
Packit Service 6d40f9
	assert (seq[5] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 5);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_insert (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	/* Note that we have a duplicate ... */
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	/* ... which doesn't show up here */
Packit Service 6d40f9
	assert_str_eq (seq[0], "1");
Packit Service 6d40f9
	assert_str_eq (seq[1], "2");
Packit Service 6d40f9
	assert_str_eq (seq[2], "3");
Packit Service 6d40f9
	assert_str_eq (seq[3], "4");
Packit Service 6d40f9
	assert_str_eq (seq[4], "5");
Packit Service 6d40f9
	assert (seq[5] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 5);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void **destroyed = NULL;
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
steal_destroyed (void *value)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int len = seq_count (destroyed);
Packit Service 6d40f9
	destroyed = seq_push (destroyed, &len, value);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_insert_destroys (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	destroyed = NULL;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (seq[0], "3");
Packit Service 6d40f9
	assert_str_eq (seq[1], "4");
Packit Service 6d40f9
	assert_str_eq (seq[2], "5");
Packit Service 6d40f9
	assert (seq[3] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (destroyed != NULL);
Packit Service 6d40f9
	assert_str_eq (destroyed[0], "3");
Packit Service 6d40f9
	assert_str_eq (destroyed[1], "3");
Packit Service 6d40f9
	assert_str_eq (destroyed[2], "4");
Packit Service 6d40f9
	assert (destroyed[3] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (destroyed, NULL);
Packit Service 6d40f9
	destroyed = NULL;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_remove (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (seq[0], "1");
Packit Service 6d40f9
	assert_str_eq (seq[1], "2");
Packit Service 6d40f9
	assert_str_eq (seq[2], "3");
Packit Service 6d40f9
	assert_str_eq (seq[3], "4");
Packit Service 6d40f9
	assert_str_eq (seq[4], "5");
Packit Service 6d40f9
	assert (seq[5] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 5);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_remove (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq_remove (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (seq[0], "1");
Packit Service 6d40f9
	assert_str_eq (seq[1], "4");
Packit Service 6d40f9
	assert_str_eq (seq[2], "5");
Packit Service 6d40f9
	assert (seq[3] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 3);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service c76c4a
static void
Packit Service c76c4a
test_remove_unsorted (void)
Packit Service c76c4a
{
Packit Service c76c4a
	void **seq = NULL;
Packit Service c76c4a
	int len = 0;
Packit Service c76c4a
Packit Service c76c4a
	seq = seq_push (seq, &len, "3");
Packit Service c76c4a
	seq = seq_push (seq, &len, "5");
Packit Service c76c4a
	seq = seq_push (seq, &len, "1");
Packit Service c76c4a
	seq = seq_push (seq, &len, "4");
Packit Service c76c4a
	seq = seq_push (seq, &len, "2");
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "3");
Packit Service c76c4a
	assert_str_eq (seq[1], "5");
Packit Service c76c4a
	assert_str_eq (seq[2], "1");
Packit Service c76c4a
	assert_str_eq (seq[3], "4");
Packit Service c76c4a
	assert_str_eq (seq[4], "2");
Packit Service c76c4a
	assert (seq[5] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 5);
Packit Service c76c4a
Packit Service c76c4a
	seq_remove_unsorted (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq_remove_unsorted (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "5");
Packit Service c76c4a
	assert_str_eq (seq[1], "1");
Packit Service c76c4a
	assert_str_eq (seq[2], "4");
Packit Service c76c4a
	assert (seq[3] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 3);
Packit Service c76c4a
Packit Service c76c4a
	seq_free (seq, NULL);
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service c76c4a
static void
Packit Service c76c4a
test_remove_first (void)
Packit Service c76c4a
{
Packit Service c76c4a
	void **seq = NULL;
Packit Service c76c4a
	int len = 0;
Packit Service c76c4a
Packit Service c76c4a
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "1");
Packit Service c76c4a
	assert_str_eq (seq[1], "2");
Packit Service c76c4a
	assert_str_eq (seq[2], "3");
Packit Service c76c4a
	assert_str_eq (seq[3], "4");
Packit Service c76c4a
	assert_str_eq (seq[4], "5");
Packit Service c76c4a
	assert (seq[5] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 5);
Packit Service c76c4a
Packit Service c76c4a
	seq_remove (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "2");
Packit Service c76c4a
	assert_str_eq (seq[1], "3");
Packit Service c76c4a
	assert_str_eq (seq[2], "4");
Packit Service c76c4a
	assert_str_eq (seq[3], "5");
Packit Service c76c4a
	assert (seq[4] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 4);
Packit Service c76c4a
Packit Service c76c4a
	seq_free (seq, NULL);
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service c76c4a
static void
Packit Service c76c4a
test_remove_last (void)
Packit Service c76c4a
{
Packit Service c76c4a
	void **seq = NULL;
Packit Service c76c4a
	int len = 0;
Packit Service c76c4a
Packit Service c76c4a
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service c76c4a
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "1");
Packit Service c76c4a
	assert_str_eq (seq[1], "2");
Packit Service c76c4a
	assert_str_eq (seq[2], "3");
Packit Service c76c4a
	assert_str_eq (seq[3], "4");
Packit Service c76c4a
	assert (seq[4] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 4);
Packit Service c76c4a
Packit Service c76c4a
	seq_remove (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service c76c4a
Packit Service c76c4a
	assert_str_eq (seq[0], "1");
Packit Service c76c4a
	assert_str_eq (seq[1], "2");
Packit Service c76c4a
	assert_str_eq (seq[2], "3");
Packit Service c76c4a
	assert (seq[3] == NULL);
Packit Service c76c4a
	assert_num_eq (len, 3);
Packit Service c76c4a
Packit Service c76c4a
	seq_free (seq, NULL);
Packit Service c76c4a
}
Packit Service c76c4a
Packit Service 6d40f9
static int
Packit Service 6d40f9
compar_even (void *match,
Packit Service 6d40f9
             void *value)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int val;
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (match, "even");
Packit Service 6d40f9
Packit Service 6d40f9
	val = atoi (value);
Packit Service 6d40f9
	if (val % 2 == 0)
Packit Service 6d40f9
		return 0;
Packit Service 6d40f9
	return -1;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_filter (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_push (seq, &len, "1");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "2");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "3");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "4");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "5");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "6");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "7");
Packit Service 6d40f9
	seq = seq_push (seq, &len, "8");
Packit Service 6d40f9
	assert (len == 8);
Packit Service 6d40f9
Packit Service 6d40f9
	destroyed = NULL;
Packit Service 6d40f9
	seq_filter (seq, &len, "even", compar_even, steal_destroyed);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (seq[0], "2");
Packit Service 6d40f9
	assert_str_eq (seq[1], "4");
Packit Service 6d40f9
	assert_str_eq (seq[2], "6");
Packit Service 6d40f9
	assert_str_eq (seq[3], "8");
Packit Service 6d40f9
	assert (seq[4] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 4);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (destroyed != NULL);
Packit Service 6d40f9
	assert_str_eq (destroyed[0], "1");
Packit Service 6d40f9
	assert_str_eq (destroyed[1], "3");
Packit Service 6d40f9
	assert_str_eq (destroyed[2], "5");
Packit Service 6d40f9
	assert_str_eq (destroyed[3], "7");
Packit Service 6d40f9
	assert (seq[4] == NULL);
Packit Service 6d40f9
	assert_num_eq (len, 4);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (destroyed, NULL);
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_filter_null (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
	seq_filter (NULL, &len, "even", compar_even, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_remove_destroys (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	destroyed = NULL;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (destroyed == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_remove (seq, &len, "5", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq_remove (seq, &len, "4", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
	seq_remove (seq, &len, "3", (seq_compar)strcmp, steal_destroyed);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (seq[0] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (destroyed != NULL);
Packit Service 6d40f9
	assert_str_eq (destroyed[0], "5");
Packit Service 6d40f9
	assert_str_eq (destroyed[1], "4");
Packit Service 6d40f9
	assert_str_eq (destroyed[2], "3");
Packit Service 6d40f9
	assert (destroyed[3] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (destroyed, NULL);
Packit Service 6d40f9
	destroyed = NULL;
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_lookup (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	char *one = "1";
Packit Service 6d40f9
	char *two = "2";
Packit Service 6d40f9
	char *three = "3";
Packit Service 6d40f9
	char *four = "4";
Packit Service 6d40f9
	char *five = "5";
Packit Service 6d40f9
	char lookup[2] = { 0, 0 };
Packit Service 6d40f9
	char *check;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, five, (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, two, (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, four, (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, three, (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, one, (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert (len == 5);
Packit Service 6d40f9
Packit Service 6d40f9
	/* Make sure not searching for same pointer */
Packit Service 6d40f9
	lookup[0] = '1';
Packit Service 6d40f9
	check = seq_lookup (seq, &len, lookup, (seq_compar)strcmp);
Packit Service 6d40f9
	assert (check == one);
Packit Service 6d40f9
Packit Service 6d40f9
	lookup[0] = '3';
Packit Service 6d40f9
	check = seq_lookup (seq, &len, lookup, (seq_compar)strcmp);
Packit Service 6d40f9
	assert (check == three);
Packit Service 6d40f9
Packit Service 6d40f9
	check = seq_lookup (seq, &len, three, (seq_compar)strcmp);
Packit Service 6d40f9
	assert (check == three);
Packit Service 6d40f9
Packit Service 6d40f9
	lookup[0] = '8';
Packit Service 6d40f9
	check = seq_lookup (seq, &len, lookup, (seq_compar)strcmp);
Packit Service 6d40f9
	assert (check == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_dup (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	void **dup;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	dup = seq_dup (seq, &len, NULL);
Packit Service 6d40f9
	assert (dup != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (dup[0], "1");
Packit Service 6d40f9
	assert_str_eq (dup[1], "2");
Packit Service 6d40f9
	assert_str_eq (dup[2], "3");
Packit Service 6d40f9
	assert_str_eq (dup[3], "4");
Packit Service 6d40f9
	assert_str_eq (dup[4], "5");
Packit Service 6d40f9
	assert (dup[5] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
	seq_free (dup, NULL);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_dup_deep (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	void **seq = NULL;
Packit Service 6d40f9
	int len = 0;
Packit Service 6d40f9
	void **dup;
Packit Service 6d40f9
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	dup = seq_dup (seq, &len, (seq_copy)strdup);
Packit Service 6d40f9
	assert (dup != NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	assert_str_eq (dup[0], "1");
Packit Service 6d40f9
	assert_str_eq (dup[1], "2");
Packit Service 6d40f9
	assert_str_eq (dup[2], "3");
Packit Service 6d40f9
	assert_str_eq (dup[3], "4");
Packit Service 6d40f9
	assert_str_eq (dup[4], "5");
Packit Service 6d40f9
	assert (dup[5] == NULL);
Packit Service 6d40f9
Packit Service 6d40f9
	seq_free (seq, NULL);
Packit Service 6d40f9
	seq_free (dup, free);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
static void
Packit Service 6d40f9
test_free_null (void)
Packit Service 6d40f9
{
Packit Service 6d40f9
	seq_free (NULL, NULL);
Packit Service 6d40f9
	seq_free (NULL, free);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
int
Packit Service 6d40f9
main (int argc,
Packit Service 6d40f9
      char *argv[])
Packit Service 6d40f9
{
Packit Service 6d40f9
	test_func (test_push, "/seq/push");
Packit Service 6d40f9
	test_func (test_insert, "/seq/insert");
Packit Service 6d40f9
	test_func (test_insert_destroys, "/seq/insert_destroys");
Packit Service 6d40f9
	test_func (test_remove, "/seq/remove");
Packit Service c76c4a
	test_func (test_remove_unsorted, "/seq/remove_unsorted");
Packit Service c76c4a
	test_func (test_remove_first, "/seq/remove_first");
Packit Service c76c4a
	test_func (test_remove_last, "/seq/remove_last");
Packit Service 6d40f9
	test_func (test_remove_destroys, "/seq/remove_destroys");
Packit Service 6d40f9
	test_func (test_filter, "/seq/filter");
Packit Service 6d40f9
	test_func (test_filter_null, "/seq/filter_null");
Packit Service 6d40f9
	test_func (test_lookup, "/seq/lookup");
Packit Service 6d40f9
	test_func (test_dup, "/seq/dup");
Packit Service 6d40f9
	test_func (test_dup_deep, "/seq/dup_deep");
Packit Service 6d40f9
	test_func (test_free_null, "/seq/free_null");
Packit Service 6d40f9
	return test_run (argc, argv);
Packit Service 6d40f9
}
Packit Service 6d40f9
Packit Service 6d40f9
#endif /* SEQ_TESTS */