util.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* Name: util.c
  2. * Author: Cecylia Bocovich <cbocovic@uwaterloo.ca>
  3. *
  4. * This file contains safe wrappers for common functions and implementations of
  5. * data structures
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "util.h"
  10. //malloc macro that exits on error
  11. void *emalloc(size_t size){
  12. void *ptr = malloc(size);
  13. if (ptr == NULL){
  14. fprintf(stderr, "Memory failure. Exiting...\n");
  15. exit(1);
  16. }
  17. return ptr;
  18. }
  19. //calloc macro that exits on error
  20. void *ecalloc(size_t nmemb, size_t size){
  21. void *ptr = calloc(nmemb, size);
  22. if(ptr == NULL){
  23. fprintf(stderr, "Memory failure. Exiting...\n");
  24. exit(1);
  25. }
  26. return ptr;
  27. }
  28. /**
  29. * Initializes a generic queue structure
  30. */
  31. queue *init_queue(){
  32. queue *new_queue = emalloc(sizeof(queue));
  33. new_queue->first = NULL;
  34. new_queue->last = NULL;
  35. return new_queue;
  36. }
  37. /**
  38. * Function to append a struct to the end of a list
  39. */
  40. void enqueue(queue *list, void *data){
  41. element *new_elem = emalloc(sizeof(element));
  42. new_elem->data = data;
  43. new_elem->next = NULL;
  44. if(list->first == NULL){
  45. list->first = new_elem;
  46. list->last = new_elem;
  47. } else {
  48. list->last->next = new_elem;
  49. list->last = new_elem;
  50. }
  51. }
  52. /**
  53. * Removes and returns the first element from the front of the list. Returns NULL
  54. * if list is empty
  55. */
  56. void *dequeue(queue *list){
  57. if(list->first == NULL){
  58. return NULL;
  59. }
  60. void *data = list->first->data;
  61. element *target =list->first;
  62. list->first = target->next;
  63. free(target);
  64. return data;
  65. }
  66. /**
  67. * Returns the nth element of the queue (as provided)
  68. *
  69. * An input of -1 peeks at last element
  70. *
  71. * Returns data on success, NULL on failure
  72. */
  73. void *peek(queue *list, int32_t n){
  74. int32_t i;
  75. element *target = list->first;
  76. if(n == -1){
  77. target = list->last;
  78. }
  79. for(i=0; (i< n) && (target == NULL); i++){
  80. target = target->next;
  81. }
  82. if(target == NULL){
  83. return NULL;
  84. } else {
  85. return target->data;
  86. }
  87. }
  88. /**
  89. * Removes (frees the data in) all elements from the list and then frees the list itself
  90. */
  91. void remove_queue(queue *list){
  92. void *data = dequeue(list);
  93. while(data != NULL){
  94. free(data);
  95. data = dequeue(list);
  96. }
  97. free(list);
  98. }