From c3d2b095b6f6775bab3d70248c66c6419ebba06a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Dec 2017 19:04:05 +0000 Subject: [PATCH] Add example demonstrating the data structure libraries --- examples/libs/data-structures/Makefile | 7 + .../libs/data-structures/data-structures.c | 383 ++++++++++++++++++ 2 files changed, 390 insertions(+) create mode 100644 examples/libs/data-structures/Makefile create mode 100644 examples/libs/data-structures/data-structures.c diff --git a/examples/libs/data-structures/Makefile b/examples/libs/data-structures/Makefile new file mode 100644 index 000000000..1f4d6b765 --- /dev/null +++ b/examples/libs/data-structures/Makefile @@ -0,0 +1,7 @@ +CONTIKI_PROJECT = data-structures + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. + +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/data-structures/data-structures.c b/examples/libs/data-structures/data-structures.c new file mode 100644 index 000000000..21752762a --- /dev/null +++ b/examples/libs/data-structures/data-structures.c @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2017, George Oikonomou - http://www.spd.gr + * Copyright (c) 2017, James Pope + * 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. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 + * COPYRIGHT HOLDER OR CONTRIBUTORS 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/stack.h" +#include "lib/queue.h" +#include "lib/circular-list.h" +#include "lib/dbl-list.h" +#include "lib/dbl-circ-list.h" +#include "lib/random.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(data_structure_process, "Data structure process"); +AUTOSTART_PROCESSES(&data_structure_process); +/*---------------------------------------------------------------------------*/ +STACK(demo_stack); +QUEUE(demo_queue); +CIRCULAR_LIST(demo_cll); +DBL_LIST(demo_dbl); +DBL_CIRC_LIST(demo_dblcl); +/*---------------------------------------------------------------------------*/ +typedef struct demo_struct_s { + struct demo_struct_s *next; + struct demo_struct_s *previous; + unsigned short value; +} demo_struct_t; +/*---------------------------------------------------------------------------*/ +#define DATA_STRUCTURE_DEMO_ELEMENT_COUNT 4 +static demo_struct_t elements[DATA_STRUCTURE_DEMO_ELEMENT_COUNT]; +/*---------------------------------------------------------------------------*/ +static void +dbl_circ_list_print(dbl_circ_list_t dblcl) +{ + demo_struct_t *this = *dblcl; + + if(*dblcl == NULL) { + printf("Length=0\n"); + return; + } + + do { + printf("<--(0x%04x)--0x%04x--(0x%04x)-->", this->previous->value, + this->value, this->next->value); + this = this->next; + } while(this != *dblcl); + + printf(" (Length=%lu)\n", dbl_circ_list_length(dblcl)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_dbl_circ_list(void) +{ + int i; + demo_struct_t *this; + + dbl_circ_list_init(demo_dblcl); + printf("============================\n"); + printf("Circular, doubly-linked list\n"); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].previous = NULL; + } + + /* Add elements */ + dbl_circ_list_add_tail(demo_dblcl, &elements[0]); + printf("Add tail : 0x%04x | ", elements[0].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_after(demo_dblcl, &elements[0], &elements[1]); + printf("Add after : 0x%04x | ", elements[1].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_head(demo_dblcl, &elements[2]); + printf("Add head : 0x%04x | ", elements[2].value); + dbl_circ_list_print(demo_dblcl); + + dbl_circ_list_add_before(demo_dblcl, &elements[2], &elements[3]); + printf("Add before: 0x%04x | ", elements[3].value); + dbl_circ_list_print(demo_dblcl); + + /* Remove head */ + this = dbl_circ_list_head(demo_dblcl); + printf("Rm head: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove currently second element */ + this = ((demo_struct_t *)dbl_circ_list_head(demo_dblcl))->next; + printf("Rm 2nd : (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove tail */ + this = dbl_circ_list_tail(demo_dblcl); + printf("Rm tail: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + /* Remove last remaining element */ + this = dbl_circ_list_tail(demo_dblcl); + printf("Rm last: (0x%04x) | ", this->value); + dbl_circ_list_remove(demo_dblcl, this); + dbl_circ_list_print(demo_dblcl); + + printf("Circular, doubly-linked list is%s empty\n", + dbl_circ_list_is_empty(demo_dblcl) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +dbl_list_print(dbl_list_t dll) +{ + demo_struct_t *this; + + for(this = *dll; this != NULL; this = this->next) { + printf("<--("); + if(this->previous == NULL) { + printf(" null "); + } else { + printf("0x%04x", this->previous->value); + } + + printf(")--0x%04x--(", this->value); + + if(this->next == NULL) { + printf(" null "); + } else { + printf("0x%04x", this->next->value); + } + printf(")-->"); + } + + printf(" (Length=%lu)\n", dbl_list_length(dll)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_dbl_list(void) +{ + int i; + demo_struct_t *this; + + dbl_list_init(demo_dbl); + printf("==================\n"); + printf("Doubly-linked list\n"); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].previous = NULL; + } + + /* Add elements */ + dbl_list_add_tail(demo_dbl, &elements[0]); + printf("Add tail : 0x%04x | ", elements[0].value); + dbl_list_print(demo_dbl); + + dbl_list_add_after(demo_dbl, &elements[0], &elements[1]); + printf("Add after : 0x%04x | ", elements[1].value); + dbl_list_print(demo_dbl); + + dbl_list_add_head(demo_dbl, &elements[2]); + printf("Add head : 0x%04x | ", elements[2].value); + dbl_list_print(demo_dbl); + + dbl_list_add_before(demo_dbl, &elements[2], &elements[3]); + printf("Add before: 0x%04x | ", elements[3].value); + dbl_list_print(demo_dbl); + + /* Remove head */ + this = dbl_list_head(demo_dbl); + printf("Rm head: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove currently second element */ + this = ((demo_struct_t *)dbl_list_head(demo_dbl))->next; + printf("Rm 2nd : (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove tail */ + this = dbl_list_tail(demo_dbl); + printf("Rm tail: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + /* Remove last remaining element */ + this = dbl_list_tail(demo_dbl); + printf("Rm last: (0x%04x) | ", this->value); + dbl_list_remove(demo_dbl, this); + dbl_list_print(demo_dbl); + + printf("Doubly-linked list is%s empty\n", + dbl_list_is_empty(demo_dbl) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +circular_list_print(circular_list_t cl) +{ + demo_struct_t *this = *cl; + + if(*cl == NULL) { + printf("Length=0\n"); + return; + } + + do { + printf("0x%04x-->", this->value); + this = this->next; + } while(this != *cl); + + printf("0x%04x (Length=%lu)\n", this->value, circular_list_length(cl)); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_circular_list(void) +{ + int i; + + circular_list_init(demo_cll); + printf("============================\n"); + printf("Circular, singly-linked list\n"); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + circular_list_add(demo_cll, &elements[i]); + + printf("Add: 0x%04x | ", elements[i].value); + circular_list_print(demo_cll); + } + + /* Remove head */ + circular_list_remove(demo_cll, circular_list_head(demo_cll)); + printf("Remove head | "); + circular_list_print(demo_cll); + + /* Remove currently second element */ + circular_list_remove(demo_cll, + ((demo_struct_t *)circular_list_head(demo_cll))->next); + printf("Remove 2nd | "); + circular_list_print(demo_cll); + + /* Remove tail */ + circular_list_remove(demo_cll, circular_list_tail(demo_cll)); + printf("Remove tail | "); + circular_list_print(demo_cll); + + /* Remove last remaining element */ + circular_list_remove(demo_cll, circular_list_tail(demo_cll)); + printf("Remove last | "); + circular_list_print(demo_cll); + + printf("Circular list is%s empty\n", + circular_list_is_empty(demo_cll) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_stack(void) +{ + int i; + demo_struct_t *this; + + printf("=====\n"); + printf("Stack\n"); + + stack_init(demo_stack); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + stack_push(demo_stack, &elements[i]); + printf("Push: 0x%04x\n", elements[i].value); + } + + printf("Peek: 0x%04x\n", + ((demo_struct_t *)stack_peek(demo_stack))->value); + + for(i = 0; i <= DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + this = stack_pop(demo_stack); + printf("Pop: "); + if(this == NULL) { + printf("(stack underflow)\n"); + } else { + printf("0x%04x\n", this->value); + } + } + printf("Stack is%s empty\n", + stack_is_empty(demo_stack) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +static void +demonstrate_queue(void) +{ + int i; + demo_struct_t *this; + + printf("=====\n"); + printf("Queue\n"); + + queue_init(demo_queue); + + /* Add elements */ + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + queue_enqueue(demo_queue, &elements[i]); + printf("Enqueue: 0x%04x\n", elements[i].value); + } + + printf("Peek: 0x%04x\n", + ((demo_struct_t *)queue_peek(demo_queue))->value); + + for(i = 0; i <= DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + this = queue_dequeue(demo_queue); + printf("Dequeue: "); + if(this == NULL) { + printf("(queue underflow)\n"); + } else { + printf("0x%04lx\n", (unsigned long)this->value); + } + } + + printf("Queue is%s empty\n", + queue_is_empty(demo_queue) ? "" : " not"); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(data_structure_process, ev, data) +{ + int i; + + PROCESS_BEGIN(); + + /* Generate some elements */ + printf("Elements: ["); + + for(i = 0; i < DATA_STRUCTURE_DEMO_ELEMENT_COUNT; i++) { + elements[i].next = NULL; + elements[i].value = random_rand(); + printf(" 0x%04x", elements[i].value); + } + printf(" ]\n"); + + demonstrate_stack(); + demonstrate_queue(); + demonstrate_circular_list(); + demonstrate_dbl_list(); + demonstrate_dbl_circ_list(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/