16cd6a6acSopenharmony_ci 26cd6a6acSopenharmony_ci/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */ 36cd6a6acSopenharmony_ci 46cd6a6acSopenharmony_ci/* FLASK */ 56cd6a6acSopenharmony_ci 66cd6a6acSopenharmony_ci/* 76cd6a6acSopenharmony_ci * Implementation of the double-ended queue type. 86cd6a6acSopenharmony_ci */ 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ci#include <stdlib.h> 116cd6a6acSopenharmony_ci#include "queue.h" 126cd6a6acSopenharmony_ci 136cd6a6acSopenharmony_ciqueue_t queue_create(void) 146cd6a6acSopenharmony_ci{ 156cd6a6acSopenharmony_ci queue_t q; 166cd6a6acSopenharmony_ci 176cd6a6acSopenharmony_ci q = (queue_t) malloc(sizeof(struct queue_info)); 186cd6a6acSopenharmony_ci if (q == NULL) 196cd6a6acSopenharmony_ci return NULL; 206cd6a6acSopenharmony_ci 216cd6a6acSopenharmony_ci q->head = q->tail = NULL; 226cd6a6acSopenharmony_ci 236cd6a6acSopenharmony_ci return q; 246cd6a6acSopenharmony_ci} 256cd6a6acSopenharmony_ci 266cd6a6acSopenharmony_ciint queue_insert(queue_t q, queue_element_t e) 276cd6a6acSopenharmony_ci{ 286cd6a6acSopenharmony_ci queue_node_ptr_t newnode; 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci if (!q) 316cd6a6acSopenharmony_ci return -1; 326cd6a6acSopenharmony_ci 336cd6a6acSopenharmony_ci newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); 346cd6a6acSopenharmony_ci if (newnode == NULL) 356cd6a6acSopenharmony_ci return -1; 366cd6a6acSopenharmony_ci 376cd6a6acSopenharmony_ci newnode->element = e; 386cd6a6acSopenharmony_ci newnode->next = NULL; 396cd6a6acSopenharmony_ci 406cd6a6acSopenharmony_ci if (q->head == NULL) { 416cd6a6acSopenharmony_ci q->head = q->tail = newnode; 426cd6a6acSopenharmony_ci } else { 436cd6a6acSopenharmony_ci q->tail->next = newnode; 446cd6a6acSopenharmony_ci q->tail = newnode; 456cd6a6acSopenharmony_ci } 466cd6a6acSopenharmony_ci 476cd6a6acSopenharmony_ci return 0; 486cd6a6acSopenharmony_ci} 496cd6a6acSopenharmony_ci 506cd6a6acSopenharmony_ciint queue_push(queue_t q, queue_element_t e) 516cd6a6acSopenharmony_ci{ 526cd6a6acSopenharmony_ci queue_node_ptr_t newnode; 536cd6a6acSopenharmony_ci 546cd6a6acSopenharmony_ci if (!q) 556cd6a6acSopenharmony_ci return -1; 566cd6a6acSopenharmony_ci 576cd6a6acSopenharmony_ci newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); 586cd6a6acSopenharmony_ci if (newnode == NULL) 596cd6a6acSopenharmony_ci return -1; 606cd6a6acSopenharmony_ci 616cd6a6acSopenharmony_ci newnode->element = e; 626cd6a6acSopenharmony_ci newnode->next = NULL; 636cd6a6acSopenharmony_ci 646cd6a6acSopenharmony_ci if (q->head == NULL) { 656cd6a6acSopenharmony_ci q->head = q->tail = newnode; 666cd6a6acSopenharmony_ci } else { 676cd6a6acSopenharmony_ci newnode->next = q->head; 686cd6a6acSopenharmony_ci q->head = newnode; 696cd6a6acSopenharmony_ci } 706cd6a6acSopenharmony_ci 716cd6a6acSopenharmony_ci return 0; 726cd6a6acSopenharmony_ci} 736cd6a6acSopenharmony_ci 746cd6a6acSopenharmony_ciqueue_element_t queue_remove(queue_t q) 756cd6a6acSopenharmony_ci{ 766cd6a6acSopenharmony_ci queue_node_ptr_t node; 776cd6a6acSopenharmony_ci queue_element_t e; 786cd6a6acSopenharmony_ci 796cd6a6acSopenharmony_ci if (!q) 806cd6a6acSopenharmony_ci return NULL; 816cd6a6acSopenharmony_ci 826cd6a6acSopenharmony_ci if (q->head == NULL) 836cd6a6acSopenharmony_ci return NULL; 846cd6a6acSopenharmony_ci 856cd6a6acSopenharmony_ci node = q->head; 866cd6a6acSopenharmony_ci q->head = q->head->next; 876cd6a6acSopenharmony_ci if (q->head == NULL) 886cd6a6acSopenharmony_ci q->tail = NULL; 896cd6a6acSopenharmony_ci 906cd6a6acSopenharmony_ci e = node->element; 916cd6a6acSopenharmony_ci free(node); 926cd6a6acSopenharmony_ci 936cd6a6acSopenharmony_ci return e; 946cd6a6acSopenharmony_ci} 956cd6a6acSopenharmony_ci 966cd6a6acSopenharmony_ciqueue_element_t queue_head(queue_t q) 976cd6a6acSopenharmony_ci{ 986cd6a6acSopenharmony_ci if (!q) 996cd6a6acSopenharmony_ci return NULL; 1006cd6a6acSopenharmony_ci 1016cd6a6acSopenharmony_ci if (q->head == NULL) 1026cd6a6acSopenharmony_ci return NULL; 1036cd6a6acSopenharmony_ci 1046cd6a6acSopenharmony_ci return q->head->element; 1056cd6a6acSopenharmony_ci} 1066cd6a6acSopenharmony_ci 1076cd6a6acSopenharmony_civoid queue_destroy(queue_t q) 1086cd6a6acSopenharmony_ci{ 1096cd6a6acSopenharmony_ci queue_node_ptr_t p, temp; 1106cd6a6acSopenharmony_ci 1116cd6a6acSopenharmony_ci if (!q) 1126cd6a6acSopenharmony_ci return; 1136cd6a6acSopenharmony_ci 1146cd6a6acSopenharmony_ci p = q->head; 1156cd6a6acSopenharmony_ci while (p != NULL) { 1166cd6a6acSopenharmony_ci free(p->element); 1176cd6a6acSopenharmony_ci temp = p; 1186cd6a6acSopenharmony_ci p = p->next; 1196cd6a6acSopenharmony_ci free(temp); 1206cd6a6acSopenharmony_ci } 1216cd6a6acSopenharmony_ci 1226cd6a6acSopenharmony_ci free(q); 1236cd6a6acSopenharmony_ci} 1246cd6a6acSopenharmony_ci 1256cd6a6acSopenharmony_ciint queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp) 1266cd6a6acSopenharmony_ci{ 1276cd6a6acSopenharmony_ci queue_node_ptr_t p; 1286cd6a6acSopenharmony_ci int ret; 1296cd6a6acSopenharmony_ci 1306cd6a6acSopenharmony_ci if (!q) 1316cd6a6acSopenharmony_ci return 0; 1326cd6a6acSopenharmony_ci 1336cd6a6acSopenharmony_ci p = q->head; 1346cd6a6acSopenharmony_ci while (p != NULL) { 1356cd6a6acSopenharmony_ci ret = f(p->element, vp); 1366cd6a6acSopenharmony_ci if (ret) 1376cd6a6acSopenharmony_ci return ret; 1386cd6a6acSopenharmony_ci p = p->next; 1396cd6a6acSopenharmony_ci } 1406cd6a6acSopenharmony_ci return 0; 1416cd6a6acSopenharmony_ci} 1426cd6a6acSopenharmony_ci 1436cd6a6acSopenharmony_civoid queue_map_remove_on_error(queue_t q, 1446cd6a6acSopenharmony_ci int (*f) (queue_element_t, void *), 1456cd6a6acSopenharmony_ci void (*g) (queue_element_t, void *), void *vp) 1466cd6a6acSopenharmony_ci{ 1476cd6a6acSopenharmony_ci queue_node_ptr_t p, last, temp; 1486cd6a6acSopenharmony_ci int ret; 1496cd6a6acSopenharmony_ci 1506cd6a6acSopenharmony_ci if (!q) 1516cd6a6acSopenharmony_ci return; 1526cd6a6acSopenharmony_ci 1536cd6a6acSopenharmony_ci last = NULL; 1546cd6a6acSopenharmony_ci p = q->head; 1556cd6a6acSopenharmony_ci while (p != NULL) { 1566cd6a6acSopenharmony_ci ret = f(p->element, vp); 1576cd6a6acSopenharmony_ci if (ret) { 1586cd6a6acSopenharmony_ci if (last) { 1596cd6a6acSopenharmony_ci last->next = p->next; 1606cd6a6acSopenharmony_ci if (last->next == NULL) 1616cd6a6acSopenharmony_ci q->tail = last; 1626cd6a6acSopenharmony_ci } else { 1636cd6a6acSopenharmony_ci q->head = p->next; 1646cd6a6acSopenharmony_ci if (q->head == NULL) 1656cd6a6acSopenharmony_ci q->tail = NULL; 1666cd6a6acSopenharmony_ci } 1676cd6a6acSopenharmony_ci 1686cd6a6acSopenharmony_ci temp = p; 1696cd6a6acSopenharmony_ci p = p->next; 1706cd6a6acSopenharmony_ci g(temp->element, vp); 1716cd6a6acSopenharmony_ci free(temp); 1726cd6a6acSopenharmony_ci } else { 1736cd6a6acSopenharmony_ci last = p; 1746cd6a6acSopenharmony_ci p = p->next; 1756cd6a6acSopenharmony_ci } 1766cd6a6acSopenharmony_ci } 1776cd6a6acSopenharmony_ci 1786cd6a6acSopenharmony_ci return; 1796cd6a6acSopenharmony_ci} 1806cd6a6acSopenharmony_ci 1816cd6a6acSopenharmony_ci/* FLASK */ 182