tests/auth/Makefile \
tests/cmd/Makefile \
tests/common/Makefile \
+ tests/opr/Makefile \
tests/util/Makefile \
tests/volser/Makefile \
src/helper-splint.sh
tests/auth/Makefile \
tests/cmd/Makefile \
tests/common/Makefile \
+tests/opr/Makefile \
tests/rpctestlib/Makefile \
tests/tap/Makefile \
tests/util/Makefile \
all: $(TOP_INCDIR)/afs/opr.h \
$(TOP_INCDIR)/afs/opr_assert.h \
+ $(TOP_INCDIR)/opr/queue.h \
$(TOP_LIBDIR)/libopr.a
libopr.a: $(objects)
$(TOP_INCDIR)/afs/opr_assert.h: opr_assert.h
$(INSTALL_DATA) opr_assert.h $@
+$(TOP_INCDIR)/opr/queue.h: queue.h
+ $(INSTALL_DATA) queue.h $@
+
+clean:
+ rm -f $(objects) libopr.a
+
install: libopr.a
$(INSTALL_DATA) libopr.a $(DESTDIR)$(libdir)/libopr.a
--- /dev/null
+/*
+ * Copyright (c) 2010 Your File System Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* A better queue implementation.
+ *
+ * This differs from the original queue implementation in that that would
+ * only allow a structure to be threaded onto a single queue. This permits
+ * a given object to be on multiple queues, providing that each queue has
+ * a place in the structure definition.
+ */
+
+#ifndef OPENAFS_OPR_QUEUE_H
+#define OPENAFS_OPR_QUEUE_H 1
+
+#ifndef KERNEL
+#include <stdlib.h>
+#else
+#ifndef NULL
+#define NULL (void *)0
+#endif
+#endif
+
+struct opr_queue {
+ struct opr_queue *next;
+ struct opr_queue *prev;
+};
+
+#define opr_queue_Scan(head, cursor) \
+ cursor = (head)->next; cursor != (head); cursor = cursor->next
+
+#define opr_queue_ScanSafe(head, cursor, store) \
+ cursor = (head)->next, store = cursor->next; \
+ cursor != (head); \
+ cursor = store, store = store->next
+
+#define opr_queue_ScanBackwards(head, cursor) \
+ cursor = (head)->prev; cursor != (head); cursor = cursor->prev
+
+#define opr_queue_ScanBackwardsSafe(head, cursor, store) \
+ cursor = (head)->prev, store = cursor->prev; \
+ cursor != (head); \
+ cursor = store, store = store->prev
+
+static_inline void
+opr_queue_Zero(struct opr_queue *q) {
+ q->prev = q->next = NULL;
+}
+
+static_inline void
+opr_queue_Init(struct opr_queue *q) {
+ q->prev = q->next = q;
+}
+
+static_inline void
+opr_queue_add(struct opr_queue *element,
+ struct opr_queue *before, struct opr_queue *after) {
+ after->prev = element;
+ element->next = after;
+ element->prev = before;
+ before->next = element;
+}
+
+static_inline void
+opr_queue_Append(struct opr_queue *queue, struct opr_queue *element) {
+ opr_queue_add(element, queue->prev, queue);
+}
+
+static_inline void
+opr_queue_Prepend(struct opr_queue *queue, struct opr_queue *element) {
+ opr_queue_add(element, queue, queue->next);
+}
+
+static_inline void
+opr_queue_InsertBefore(struct opr_queue *exist, struct opr_queue *adding) {
+ /* This may seem back to front, but take a list A, B, C where we want
+ * to add 1 before B. So, we're adding 1 with A the element before,
+ * and B the element after, hence the following: */
+ opr_queue_add(adding, exist->prev, exist);
+}
+
+static_inline void
+opr_queue_InsertAfter(struct opr_queue *exist, struct opr_queue *adding) {
+ opr_queue_add(adding, exist, exist->next);
+}
+
+static_inline void
+opr_queue_Remove(struct opr_queue *element) {
+ element->next->prev = element->prev;
+ element->prev->next = element->next;
+ element->prev = NULL;
+ element->next = NULL;
+}
+
+static_inline int
+opr_queue_IsEmpty(struct opr_queue *q) {
+ return (q->prev == q);
+}
+
+static_inline int
+opr_queue_IsOnQueue(struct opr_queue *q) {
+ return (q->prev != NULL);
+}
+
+static_inline int
+opr_queue_IsEnd(struct opr_queue *q, struct opr_queue *cursor) {
+ return (cursor->next == q);
+}
+
+static_inline int
+opr_queue_Count(struct opr_queue *q) {
+ struct opr_queue *cursor;
+ int n = 0;
+
+ for (opr_queue_Scan(q, cursor)) {
+ n++;
+ }
+ return n;
+}
+
+/* Remove the members before pivot from Q1, and append them to Q2 */
+
+static_inline void
+opr_queue_SplitBeforeAppend(struct opr_queue *q1, struct opr_queue *q2,
+ struct opr_queue *pivot) {
+
+ if (q1 == pivot->prev)
+ return;
+ /* Add ourselves to the end of list 2 */
+ q2->prev->next = q1->next; /* end of list 2, is now the start of list 1 */
+ q1->next->prev = q2->prev;
+ pivot->prev->next = q2; /* entry before the pivot is it at end of q2 */
+ q2->prev = pivot->prev;
+
+ /* Pull ourselves out of list q1. */
+ q1->next = pivot;
+ pivot->prev = q1;
+}
+
+/* Remove the members after the pivot from Q1, and prepend them onto Q2 */
+static_inline void
+opr_queue_SplitAfterPrepend(struct opr_queue *q1, struct opr_queue *q2,
+ struct opr_queue *pivot) {
+
+ if (q1 == pivot->next)
+ return;
+
+ /* start of q2 has last element of q1 before it */
+ q2->next->prev = q1->prev;
+ q1->prev->next = q2->next;
+ /* item that we're breaking at (pivot->next) is at start of q2 */
+ q2->next = pivot->next;
+ pivot->next->prev = q2;
+
+ /* Q1 now ends after pivot */
+ pivot->next = q1;
+ q1->prev = pivot;
+}
+
+static_inline void
+opr_queue_SpliceAppend(struct opr_queue *target, struct opr_queue *source)
+{
+
+ if (source->next == source)
+ return;
+
+ /* Stick the contents of source onto the end of target */
+ target->prev->next = source->next;
+ source->next->prev = target->prev;
+ source->prev->next = target;
+ target->prev = source->prev;
+
+ /* Reinitialise source */
+ source->next = source->prev = source;
+}
+
+static_inline void
+opr_queue_SplicePrepend(struct opr_queue *target, struct opr_queue *source)
+{
+
+ if (source->next == source)
+ return;
+
+ /* Contents of source go onto the beginning of target */
+ target->next->prev = source->prev;
+ source->prev->next = target->next;
+ source->next->prev = target;
+ target->next = source->next;
+
+ /* Reinitialise source */
+ source->next = source->prev = source;
+}
+
+#define opr_queue_Entry(queue, structure, member) \
+ ((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
+
+#define opr_queue_First(queue, structure, member) \
+ opr_queue_Entry((queue)->next, structure, member)
+
+#define opr_queue_Last(queue, structure, member) \
+ opr_queue_Entry((queue)->prev, structure, member)
+
+#define opr_queue_Next(entry, structure, member) \
+ opr_queue_Entry((entry)->next, structure, member)
+
+#define opr_queue_Prev(entry, structure, member) \
+ opr_queue_Entry((entry)->prev, structure, member)
+
+#endif
${TOP_INCDIR}/afs/work_queue_types.h \
${TOP_INCDIR}/afs/thread_pool.h \
${TOP_INCDIR}/afs/thread_pool_types.h \
- ${TOP_INCDIR}/afs/tabular_output.h \
- ${TOP_INCDIR}/opr/queue.h
+ ${TOP_INCDIR}/afs/tabular_output.h
all: ${includes} \
${TOP_LIBDIR}/util.a \
${TOP_INCDIR}/potpourri.h: ${srcdir}/potpourri.h
${INSTALL_DATA} $? $@
-${TOP_INCDIR}/opr/queue.h: ${srcdir}/queue.h
- ${INSTALL_DATA} $? $@
-
${TOP_LIBDIR}/util.a: util.a
${INSTALL_DATA} $? $@
+++ /dev/null
-/*
- * Copyright (c) 2010 Your File System Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* A better queue implementation.
- *
- * This differs from the original queue implementation in that that would
- * only allow a structure to be threaded onto a single queue. This permits
- * a given object to be on multiple queues, providing that each queue has
- * a place in the structure definition.
- */
-
-#ifndef OPENAFS_OPR_QUEUE_H
-#define OPENAFS_OPR_QUEUE_H 1
-
-#ifndef KERNEL
-#include <stdlib.h>
-#else
-#ifndef NULL
-#define NULL (void *)0
-#endif
-#endif
-
-struct opr_queue {
- struct opr_queue *next;
- struct opr_queue *prev;
-};
-
-#define opr_queue_Scan(head, cursor) \
- cursor = (head)->next; cursor != (head); cursor = cursor->next
-
-#define opr_queue_ScanSafe(head, cursor, store) \
- cursor = (head)->next, store = cursor->next; \
- cursor != (head); \
- cursor = store, store = store->next
-
-#define opr_queue_ScanBackwards(head, cursor) \
- cursor = (head)->prev; cursor != (head); cursor = cursor->prev
-
-#define opr_queue_ScanBackwardsSafe(head, cursor, store) \
- cursor = (head)->prev, store = cursor->prev; \
- cursor != (head); \
- cursor = store, store = store->prev
-
-static_inline void
-opr_queue_Zero(struct opr_queue *q) {
- q->prev = q->next = NULL;
-}
-
-static_inline void
-opr_queue_Init(struct opr_queue *q) {
- q->prev = q->next = q;
-}
-
-static_inline void
-opr_queue_add(struct opr_queue *element,
- struct opr_queue *before, struct opr_queue *after) {
- after->prev = element;
- element->next = after;
- element->prev = before;
- before->next = element;
-}
-
-static_inline void
-opr_queue_Append(struct opr_queue *queue, struct opr_queue *element) {
- opr_queue_add(element, queue->prev, queue);
-}
-
-static_inline void
-opr_queue_Prepend(struct opr_queue *queue, struct opr_queue *element) {
- opr_queue_add(element, queue, queue->next);
-}
-
-static_inline void
-opr_queue_InsertBefore(struct opr_queue *exist, struct opr_queue *adding) {
- /* This may seem back to front, but take a list A, B, C where we want
- * to add 1 before B. So, we're adding 1 with A the element before,
- * and B the element after, hence the following: */
- opr_queue_add(adding, exist->prev, exist);
-}
-
-static_inline void
-opr_queue_InsertAfter(struct opr_queue *exist, struct opr_queue *adding) {
- opr_queue_add(adding, exist, exist->next);
-}
-
-static_inline void
-opr_queue_Remove(struct opr_queue *element) {
- element->next->prev = element->prev;
- element->prev->next = element->next;
- element->prev = NULL;
- element->next = NULL;
-}
-
-static_inline int
-opr_queue_IsEmpty(struct opr_queue *q) {
- return (q->prev == q);
-}
-
-static_inline int
-opr_queue_IsOnQueue(struct opr_queue *q) {
- return (q->prev != NULL);
-}
-
-static_inline int
-opr_queue_IsEnd(struct opr_queue *q, struct opr_queue *cursor) {
- return (cursor->next == q);
-}
-
-static_inline int
-opr_queue_Count(struct opr_queue *q) {
- struct opr_queue *cursor;
- int n = 0;
-
- for (opr_queue_Scan(q, cursor)) {
- n++;
- }
- return n;
-}
-
-/* Remove the members before pivot from Q1, and append them to Q2 */
-
-static_inline void
-opr_queue_SplitBeforeAppend(struct opr_queue *q1, struct opr_queue *q2,
- struct opr_queue *pivot) {
-
- if (q1 == pivot->prev)
- return;
- /* Add ourselves to the end of list 2 */
- q2->prev->next = q1->next; /* end of list 2, is now the start of list 1 */
- q1->next->prev = q2->prev;
- pivot->prev->next = q2; /* entry before the pivot is it at end of q2 */
- q2->prev = pivot->prev;
-
- /* Pull ourselves out of list q1. */
- q1->next = pivot;
- pivot->prev = q1;
-}
-
-/* Remove the members after the pivot from Q1, and prepend them onto Q2 */
-static_inline void
-opr_queue_SplitAfterPrepend(struct opr_queue *q1, struct opr_queue *q2,
- struct opr_queue *pivot) {
-
- if (q1 == pivot->next)
- return;
-
- /* start of q2 has last element of q1 before it */
- q2->next->prev = q1->prev;
- q1->prev->next = q2->next;
- /* item that we're breaking at (pivot->next) is at start of q2 */
- q2->next = pivot->next;
- pivot->next->prev = q2;
-
- /* Q1 now ends after pivot */
- pivot->next = q1;
- q1->prev = pivot;
-}
-
-static_inline void
-opr_queue_SpliceAppend(struct opr_queue *target, struct opr_queue *source)
-{
-
- if (source->next == source)
- return;
-
- /* Stick the contents of source onto the end of target */
- target->prev->next = source->next;
- source->next->prev = target->prev;
- source->prev->next = target;
- target->prev = source->prev;
-
- /* Reinitialise source */
- source->next = source->prev = source;
-}
-
-static_inline void
-opr_queue_SplicePrepend(struct opr_queue *target, struct opr_queue *source)
-{
-
- if (source->next == source)
- return;
-
- /* Contents of source go onto the beginning of target */
- target->next->prev = source->prev;
- source->prev->next = target->next;
- source->next->prev = target;
- target->next = source->next;
-
- /* Reinitialise source */
- source->next = source->prev = source;
-}
-
-#define opr_queue_Entry(queue, structure, member) \
- ((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
-
-#define opr_queue_First(queue, structure, member) \
- opr_queue_Entry((queue)->next, structure, member)
-
-#define opr_queue_Last(queue, structure, member) \
- opr_queue_Entry((queue)->prev, structure, member)
-
-#define opr_queue_Next(entry, structure, member) \
- opr_queue_Entry((entry)->next, structure, member)
-
-#define opr_queue_Prev(entry, structure, member) \
- opr_queue_Entry((entry)->prev, structure, member)
-
-#endif
MODULE_CFLAGS = -DSOURCE='"$(abs_top_srcdir)/tests"' \
-DBUILD='"$(abs_top_builddir)/tests"'
-SUBDIRS = tap common auth util cmd volser
+SUBDIRS = tap common auth util cmd volser opr
all: runtests
@for A in $(SUBDIRS); do cd $$A && $(MAKE) $@ && cd .. || exit 1; done
util/ktime
util/exec-alt
-util/queues
auth/keys
auth/superuser
auth/authcon
cmd/command
+opr/queues
ptserver/pt_util
ptserver/pts-man
volser/vos-man
--- /dev/null
+srcdir=@srcdir@
+abs_top_builddir=@abs_top_builddir@
+include @TOP_OBJDIR@/src/config/Makefile.config
+include @TOP_OBJDIR@/src/config/Makefile.lwp
+
+MODULE_CFLAGS = -I$(srcdir)/..
+
+LIBS=../tap/libtap.a $(abs_top_builddir)/lib/libopr.a
+
+tests = queues-t
+
+all check test tests: $(tests)
+
+queues-t: queues-t.o
+ $(AFS_LDRULE) queues-t.o ../tap/libtap.a $(XLIBS)
+
+clean distclean:
+ $(RM) -f $(tests) *.o core
--- /dev/null
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include <stdlib.h>
+
+#include <tap/basic.h>
+
+#include <opr/queue.h>
+
+
+struct charqueue {
+ struct opr_queue entry;
+ char item;
+};
+
+
+struct charqueue *
+newEntry(char string)
+{
+ struct charqueue *entry;
+
+ entry=malloc(sizeof(struct charqueue));
+ entry->item=string;
+ return(entry);
+}
+
+char *
+queueAsString(struct opr_queue *head) {
+ static char items[255];
+ struct opr_queue *cursor;
+ int pos = 0;
+
+ for(opr_queue_Scan(head, cursor)) {
+ items[pos] = opr_queue_Entry(cursor, struct charqueue, entry)->item;
+ pos++;
+ if (pos==254)
+ break;
+ }
+ items[pos]='\0';
+
+ return items;
+}
+
+void
+stringIntoQueue(char *string, struct opr_queue *q) {
+ int i;
+
+ i = 0;
+ while (string[i]!='\0') {
+ opr_queue_Append(q, &(newEntry(string[i])->entry));
+ i++;
+ }
+}
+
+int
+main(void)
+{
+ struct opr_queue q1, q2, *cursor;
+
+ plan(12);
+
+ opr_queue_Init(&q1);
+ opr_queue_Init(&q2);
+
+ opr_queue_Append(&q1, &(newEntry('A')->entry));
+ opr_queue_Append(&q1, &(newEntry('B')->entry));
+ opr_queue_Append(&q1, &(newEntry('C')->entry));
+ is_string(queueAsString(&q1), "ABC", "Append works as expected");
+
+ opr_queue_Prepend(&q1, &(newEntry('D')->entry));
+ opr_queue_Prepend(&q1, &(newEntry('E')->entry));
+ is_string(queueAsString(&q1), "EDABC", "Prepend works");
+
+ opr_queue_Append(&q2, &(newEntry('1')->entry));
+ opr_queue_Append(&q2, &(newEntry('2')->entry));
+
+ opr_queue_SpliceAppend(&q1, &q2);
+ is_string(queueAsString(&q1), "EDABC12", "SpliceAppend works");
+ ok(opr_queue_IsEmpty(&q2),
+ "IsEmpty works (and splice empties queues)");
+
+ opr_queue_Append(&q2, &(newEntry('8')->entry));
+ opr_queue_Append(&q2, &(newEntry('9')->entry));
+ is_string(queueAsString(&q2), "89", "Append works again");
+
+ opr_queue_SplicePrepend(&q1, &q2);
+ is_string(queueAsString(&q1), "89EDABC12", "SplicePrepend works");
+
+ /* Now for some trickier stuff */
+ stringIntoQueue("XYZ", &q2);
+
+ /* Find the A in the string above */
+ for (opr_queue_Scan(&q1, cursor)) {
+ if (opr_queue_Entry(cursor, struct charqueue, entry)->item == 'A')
+ break;
+ }
+
+ opr_queue_InsertBefore(cursor, &(newEntry('M')->entry));
+ is_string("89EDMABC12", queueAsString(&q1),
+ "InsertBefore functions correctly");
+ opr_queue_SplitBeforeAppend(&q1, &q2, cursor);
+ is_string("ABC12", queueAsString(&q1),
+ "SplitBefore leaves old queue in correct state");
+ is_string("XYZ89EDM", queueAsString(&q2),
+ "SplitBefore correctly appends to new queue");
+
+ /* Find the 9 in q2 */
+ for (opr_queue_Scan(&q2, cursor)) {
+ if (opr_queue_Entry(cursor, struct charqueue, entry)->item == '9')
+ break;
+ }
+ opr_queue_InsertAfter(cursor, &(newEntry('N')->entry));
+ is_string("XYZ89NEDM", queueAsString(&q2), "InsertAfter");
+
+ opr_queue_SplitAfterPrepend(&q2, &q1, cursor);
+ is_string("NEDMABC12", queueAsString(&q1), "SplitAfterPrepend Q1");
+ is_string("XYZ89", queueAsString(&q2), "SplitAfterPrepend Q2");
+
+ return 0;
+}
LIBS = ../tap/libtap.a $(abs_top_builddir)/lib/util.a
-tests = ktime-t exec-alt-t queues-t
+tests = ktime-t exec-alt-t
all check test tests: $(tests)
exec-alt-t: exec-alt-t.o $(LIBS)
$(AFS_LDRULE) exec-alt-t.o $(LIBS) $(XLIBS)
-queues-t: queues-t.o
- $(AFS_LDRULE) queues-t.o ../tap/libtap.a $(XLIBS)
-
install:
clean distclean:
+++ /dev/null
-#include <afsconfig.h>
-#include <afs/param.h>
-
-#include <stdlib.h>
-
-#include <tap/basic.h>
-
-#include <opr/queue.h>
-
-
-struct charqueue {
- struct opr_queue entry;
- char item;
-};
-
-
-struct charqueue *
-newEntry(char string)
-{
- struct charqueue *entry;
-
- entry=malloc(sizeof(struct charqueue));
- entry->item=string;
- return(entry);
-}
-
-char *
-queueAsString(struct opr_queue *head) {
- static char items[255];
- struct opr_queue *cursor;
- int pos = 0;
-
- for(opr_queue_Scan(head, cursor)) {
- items[pos] = opr_queue_Entry(cursor, struct charqueue, entry)->item;
- pos++;
- if (pos==254)
- break;
- }
- items[pos]='\0';
-
- return items;
-}
-
-void
-stringIntoQueue(char *string, struct opr_queue *q) {
- int i;
-
- i = 0;
- while (string[i]!='\0') {
- opr_queue_Append(q, &(newEntry(string[i])->entry));
- i++;
- }
-}
-
-int
-main(void)
-{
- struct opr_queue q1, q2, *cursor;
-
- plan(12);
-
- opr_queue_Init(&q1);
- opr_queue_Init(&q2);
-
- opr_queue_Append(&q1, &(newEntry('A')->entry));
- opr_queue_Append(&q1, &(newEntry('B')->entry));
- opr_queue_Append(&q1, &(newEntry('C')->entry));
- is_string(queueAsString(&q1), "ABC", "Append works as expected");
-
- opr_queue_Prepend(&q1, &(newEntry('D')->entry));
- opr_queue_Prepend(&q1, &(newEntry('E')->entry));
- is_string(queueAsString(&q1), "EDABC", "Prepend works");
-
- opr_queue_Append(&q2, &(newEntry('1')->entry));
- opr_queue_Append(&q2, &(newEntry('2')->entry));
-
- opr_queue_SpliceAppend(&q1, &q2);
- is_string(queueAsString(&q1), "EDABC12", "SpliceAppend works");
- ok(opr_queue_IsEmpty(&q2),
- "IsEmpty works (and splice empties queues)");
-
- opr_queue_Append(&q2, &(newEntry('8')->entry));
- opr_queue_Append(&q2, &(newEntry('9')->entry));
- is_string(queueAsString(&q2), "89", "Append works again");
-
- opr_queue_SplicePrepend(&q1, &q2);
- is_string(queueAsString(&q1), "89EDABC12", "SplicePrepend works");
-
- /* Now for some trickier stuff */
- stringIntoQueue("XYZ", &q2);
-
- /* Find the A in the string above */
- for (opr_queue_Scan(&q1, cursor)) {
- if (opr_queue_Entry(cursor, struct charqueue, entry)->item == 'A')
- break;
- }
-
- opr_queue_InsertBefore(cursor, &(newEntry('M')->entry));
- is_string("89EDMABC12", queueAsString(&q1),
- "InsertBefore functions correctly");
- opr_queue_SplitBeforeAppend(&q1, &q2, cursor);
- is_string("ABC12", queueAsString(&q1),
- "SplitBefore leaves old queue in correct state");
- is_string("XYZ89EDM", queueAsString(&q2),
- "SplitBefore correctly appends to new queue");
-
- /* Find the 9 in q2 */
- for (opr_queue_Scan(&q2, cursor)) {
- if (opr_queue_Entry(cursor, struct charqueue, entry)->item == '9')
- break;
- }
- opr_queue_InsertAfter(cursor, &(newEntry('N')->entry));
- is_string("XYZ89NEDM", queueAsString(&q2), "InsertAfter");
-
- opr_queue_SplitAfterPrepend(&q2, &q1, cursor);
- is_string("NEDMABC12", queueAsString(&q1), "SplitAfterPrepend Q1");
- is_string("XYZ89", queueAsString(&q2), "SplitAfterPrepend Q2");
-
- return 0;
-}
-
-