Blame library/seq.c

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