User Tools

Site Tools


queue_resources

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

queue_resources [2023/01/09 14:24]
scott [queue.h]
queue_resources [2023/01/09 14:31] (current)
scott [queue.c]
Line 141: Line 141:
  
 <file C queue.c> <file C queue.c>
-#include <​stdio.h>​ + 
-#include <​stdlib.h>​ +#include <​stdio.h> ​ // printf 
-#include <​string.h>​+#include <​stdlib.h> ​// malloc, free, abort 
 +#include <​string.h> ​// strncpy 
 #include "​queue.h"​ #include "​queue.h"​
-#include <​assert.h>​ 
  
-// Uncomment line below to print out informational messages during ​queue operation+// Allocates memory for the queue (the data* pointer) and initializes all 
-// #define QUEUE_PRINT_INFO_MESSAGES+// parts of the data structure. Prints out an error message if malloc() fails 
 +// and calls assert(false) ​to print-out line-number information and die. 
 +// The queue is empty after initializationTo fill the queue with known 
 +// values (e.g. zeros), call queue_overwritePush() up to queue_size() times. 
 +void queue_init(queue_t *q, queue_size_t size, const char *name) 
 +
 + // Always points to the next open slot. 
 + q->​indexIn = 0; 
 + // Always points to the next element to be removed 
 + // from the queue (or "​oldest"​ element). 
 + q->​indexOut = 0; 
 + // Keep track of the number of elements currently in queue. 
 + q->​elementCount = 0; 
 + // Queue capacity. 
 + q->size = size; 
 + // Points to a dynamically-allocated array. 
 + q->data = malloc(size * sizeof(queue_data_t));​ 
 + if (q->data == NULL) abort(); 
 + // True if queue_pop() is called on an empty queue. Reset 
 + // to false after queue_push() is called. 
 + q->​underflowFlag = false; 
 + // True if queue_push() is called on a full queue. Reset to 
 + // false once queue_pop() is called. 
 + q->​overflowFlag = false; 
 + // Name for debugging purposes. 
 + strncpy(q->​name,​ name, QUEUE_MAX_NAME_SIZE);​ 
 + q->​name[QUEUE_MAX_NAME_SIZE-1] = '​\0';​ 
 +}
  
-// Standard ​queue implementation that leaves one spot empty so easier to check for full/empty+// Get the user-assigned name for the queue. 
-void queue_init(queue_t* q, queue_size_t size, const char* name) { +const char *queue_name(queue_t ​*q) 
-  q->​underflowFlag = false; ​ // True if queue_pop() is called on an empty queue. +
-  q-> overflowFlag = false; ​ // True if queue_push() is called on a full queue. + return ​q->name;
-  q->​indexIn = 0; +
-  q->​indexOut = 0; +
-  q->​elementCount = 0;       // Not required but may ease implementation. +
-  q->size = size+1; // Add one additional location for the empty location; size is data-array size, exactly. +
-  q->data = (queue_data_t ​*) malloc(q->size * sizeof(queue_data_t)); +
-  if (q->data == 0) +
-  ​ printf("​Error!!!:​ queue_init() failed to allocate the required memory in queue_init()!!! (%ld).\n\r",​ size); +
-  printf("​Check your heap and stack size and set them both to 2,000,000 bytes (2,000 kB).\n\r"​);​ +
-  printf("​View Video V11 on the ECEn 330 YouTube channel to see how to set heap and stack size.\n\r"​);​ +
-  printf("​Copy this link to your browser: https://​www.youtube.com/​watch?​v=onO-XojGFMM&​feature=youtu.be\n\r"​);​ +
-  assert(false);​ +
-  } +
-  strncpy(q->name, name, QUEUE_MAX_NAME_SIZE); +
-#ifdef QUEUE_PRINT_INFO_MESSAGES +
-  printf("​initialized %s.\n\r",​ q->​name);​ +
-#endif+
 } }
  
-// Tell the user size in terms of usable locations+// Returns ​the capacity ​of the queue
-queue_size_t queue_size(queue_t* q) {return q->size-1;}+queue_size_t queue_size(queue_t *q) 
 +{ 
 + return q->size; 
 +}
  
-// Return the name of the queue. +// Returns true if the queue is full
-const char* queue_name(queue_t* q) {return q->name;}+bool queue_full(queue_t *q) 
 +{ 
 +}
  
-// Just free the data array in the queue. +// Returns true if the queue is empty
-void queue_garbageCollect(queue_t* q) { +bool queue_empty(queue_t *q) 
-  free(q->​data);​+{
 } }
  
-/​******************************************************** +// If the queue is not fullpushes a new element into the queue and clears ​the 
-************* Test Code starts here. ******************** +// underflowFlagIF the queue is full, set the overflowFlagprint an error 
-****** invoke queue_runTest() to run test code. ********* +// message and DO NOT change ​the queue. 
-********************************************************/​ +void queue_push(queue_t ​*q, queue_data_t value
- +{
-// Used to check the status of the queue flags. +
-// Returns true if the all of the queue status matches values of the arguments. +
-// Returns false otherwise. +
-// Prints informational messages if the queue status does not match the provided argument values. +
-static bool queue_printQueueStatus(queue_t* qbool overflowArg,​ bool underflowArg,​ bool fullArg, bool emptyArg) { +
-  bool result = true; +
-  bool flag; +
-  if ((flag=queue_overflow(q)) != overflowArg) {  // Check the queue status against ​the flag. +
-    ​result = flag ? result: false; ​               ​// Note failure. +
-    if (flag) ​                                    // Print helpful informational messages. +
-      printf("​* queue_overFlow(%s) returned true. Should have returned false.\n\r",​ q->​name);​ +
-    else +
-      printf("​* queue_overFlow(%s) returned false. Should have returned true.\n\r",​ q->​name);​ +
-  } +
-  if ((flag=queue_underflow(q)) != underflowArg) {  // Check the queue status against ​the flag. +
-    result = flag ? result: false; ​                 // Note failure. +
-    if (flag) ​                                      // Print helpful informational messages. +
-      printf("​* queue_underFlow(%s) returned true. Should have returned false.\n\r"​q->​name);​ +
-    ​else +
-      printf("​* queue_underFlow(%s) returned false. Should have returned true.\n\r",​ q->​name);​ +
-  } +
-  if ((flag=queue_full(q)) != fullArg) {  ​// Check the queue status against the flag+
-    ​result = flag ? result: false; ​       // Note failure. +
-    if (flag) {                           // Print helpful informational messages. +
-      printf("​queue_full(%s) returned true. Should have returned false.\n\r", ​q->​name);​ +
-      printf("​* queue: %s contains %ld elements.\n\r"​queue_name(q), queue_elementCount(q));​ +
-    } +
-    else { +
-      printf("​* queue_full(%s) returned false. Should have returned true.\n\r",​ q->​name);​ +
-      printf("​* queue: %s contains %ld elements.\n\r",​ queue_name(q),​ queue_elementCount(q));​ +
-    } +
-  } +
-  if ((flag=queue_empty(q)) != emptyArg) {  // Check the queue status against the flag. +
-    result = flag ? result: false; ​         // Note failure. +
-    if (flag) {                              // Print helpful informational messages. +
-      printf("​* queue_empty(%s) returned true. Should have returned false.\n\r",​ q->​name);​ +
-    } +
-    else { +
-      printf("​* queue_empty(%s) returned false. Should have returned true.\n\r",​ q->​name);​ +
-      printf("​* queue: %s contains %ld elements.\n\r",​ queue_name(q),​ queue_elementCount(q));​ +
-    } +
-  } +
-  return result;+
 } }
  
-// Assumes testQ is filled with the contents from dataArray. +// If the queue is not empty, remove ​and return ​the oldest element in the queue. 
-// Repeatedly calls queue_pop until all of the queue contents have been removed. +// If the queue is emptyset the underflowFlagprint an error message, and DO 
-// Uses queue_pop() ​and queue_readElementAt(). +// NOT change ​the queue. 
-// Reads the entire contents of the queue after each pop+queue_data_t ​queue_pop(queue_t *q
-static bool queue_emptyTest(queue_t* testQ, double* dataArray, queue_size_t arraySize) { +{
-  bool tempResult = true; +
-  bool testResult = true; +
-  for (int32_t testDataIndex=arraySize-1;​ testDataIndex>​=0;​ testDataIndex--) { +
-    ​// First, pop an element of the queue and check to see if the pop'd value is correct. +
-    double poppedValue = queue_pop(testQ);​ +
-    tempResult = true; +
-    if (poppedValue != dataArray[arraySize-(testDataIndex+1)]) { +
-      printf("​* Error: queue_pop() returned %lfshould have returned %lf.\n\r"​poppedValuedataArray[arraySize-(testDataIndex+1)]);​ +
-      printf("​* queue_pop invoked %ld times, testDataIndex:​ %ld\n\r",​ arraySize-(testDataIndex+1),​ testDataIndex);​ +
-      tempResult = false; +
-      printf("​* queue_pop() failed. Recommend that you fix this problem before proceeding further.\n\r"​);​ +
-      return false; +
-    } +
-    testResult = tempResult ? testResult : false; // Just a logical AND of testResult ​and tempResult. +
-    // Next, read all of the remaining elements in the queue to see if they are correct+
-    // Because you are using queue_pop(), you must offset the indicies for the array, +
-    // moving forward after each pop. The indices used with queue_readElementAt() are not offset. +
-    tempResult = true; +
-    for (int32_t queueIndex=0;​ queueIndex<​testDataIndex;​ queueIndex++) ​{ +
-      double temp; +
-      if ((temp=queue_readElementAt(testQ,​ queueIndex)) != dataArray[arraySize-(testDataIndex)+queueIndex]) { +
-        printf("​* Error: queue_readElementAt(%ld) read %lf, queue should contain %lf.\n\r",​ queueIndex, temp, dataArray[arraySize-(testDataIndex)+queueIndex]);​ +
-        printf("​* Either queue_pop() or queue_readElementAt() contains a bug.\n\r"​);​ +
-        printf("​* Repair this bug before proceeding further.\n\r"​);​ +
-        tempResult = false; +
-      } +
-    } +
-    testResult = tempResult ? testResult : false; // Just a logical AND of testResult and tempResult. +
-    // Pop a value and check to see if correct. +
-  } +
-  tempResult=queue_printQueueStatus(testQ,​ false, false, false, true); +
-  testResult = tempResult ? testResult : false; // Just a logical AND of testResult and tempResult. +
-  return testResult;+
 } }
  
-// Assumes an initialized queue. Fills the queue with the contents of dataArray using queue_push(). +// If the queue is fullcall queue_pop() and then call queue_push(). 
-// Each time data is pushedqueue_readElementAt() is invoked to ensure the queue contains the +// If the queue is not fulljust call queue_push(). 
-// correct data. This test will pass if queue_push() and queue_readElementAt() work correctly. +void queue_overwritePush(queue_t *qqueue_data_t value
-static bool queue_fillTest(queue_t* testQ, double* dataArray, queue_size_t arraySize) { +{
-  bool testResult = true;  // Keep track of the results of the test. +
-  uint32_t testDataIndex = 0;  // Just an index. +
-  for (testDataIndex=0;​ testDataIndex<​arraySize;​ testDataIndex++) { // Iterate across the dataArray. +
-    ​queue_push(testQ, dataArray[testDataIndex]);  // Push a value onto the queue+
-    ​double temp;  ​// Keep track of the value ready by queue_readElementAt(). +
-    // Read all elements currently in queue and check to see that they match against the data contained in dataArray. +
-    if ((temp=queue_readElementAt(testQ,​ testDataIndex) != dataArray[testDataIndex])) { +
-      printf("​* Error: queue_readElementAt() failed. push value %lf does not match read value %lf.\n\r"​, +
-          temp, dataArray[testDataIndex]);​ +
-      printf("​* Bug is likely in queue_push() or queue_readElementAt().\n\r"​);​ +
-      ​testResult = false; ​ // Failed the test. +
-      break; ​              // Stop iterating at this point. +
-    } +
-  } +
-  // Queue should be full at this point with no overflow or underflow, argument order:(overflowunderflow, full, empty). +
-  bool tempResult = true;  // Keep track of the queue_printQueueStatus() test. +
-  if (testResult) ​{ +
-    tempResult=queue_printQueueStatus(testQ,​ false, false, true, false); ​ // See comment above for argument order. +
-  } +
-  testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-  return testResult;+
 } }
  
-// Builds a test queue and applies a series of pushes and pops. +// Provides random-access read capability ​to the queue. 
-// The value returned by queue_pop() is checked for correctness. +// Low-valued indexes access older queue elements while higher-value indexes 
-// queue_elementCount() is also checked frequently ​to ensure that +// access newer elements (according ​to the order that they were added)Print a 
-// it returns ​the correct value. +// meaningful ​error message ​if an error condition is detected. 
-// To perform the test, a non-circular ​queue is implemented as +queue_data_t queue_readElementAt(queue_t *qqueue_index_t index
-// a simple array with a ncqPushIndexPtr and a ncqPopIndexPtrThe +{
-// queue code under test should exhibit the same behavior as the non-circular ​queue+
-// The non-circular queue is initialized to contain random values. +
-// Values from the non-circular queue are from the ncqPushIndexPtr +
-// and values ​to be popped from the queue under test are compared +
-// to the ncqPopIndexPtr locationThe test terminates upon detecting an +
-// error or if no error has been detected ​and the entire contents of the +
-// non-circular queue have been pushed into the test Q and then pop'​d +
-// from the test queue+
-#define PUSH_POP_Q_SIZE 100        // The size of the queue. +
-#define NON_CIRC_Q_SIZE 1000       // Size of noncircularQ used to test the testQ. +
-#define MAX_PUSH_POP_COUNT 20      // Maximum number of pushes or pops in one pass. +
-#define PUSH_POP_Q_NAME "​pushPopQ"​ // Name the queue. +
-static bool queue_pushPopTest() { +
-  bool testResult = true; +
-  bool tempResult = true; +
-  // ncq: non-circular queue +
-  double* ncq = (double *) malloc(NON_CIRC_Q_SIZE * sizeof(double));​ +
-  for (uint16_t i=0; i<​NON_CIRC_Q_SIZE;​ i++) {  // Fill up the non-circular queue with data. +
-    ncq[i] = (double) rand(); +
-  } +
-  // Emulate a simple non-circular queue for testing purposes. +
-  uint16_t ncqPopIndexPtr = 0;  // The pop-pointer for the non-circular queue. +
-  uint16_t ncqPushIndexPtr = 0; // The push-pointer for the non-circular queue. +
-  ​queue_t ​testQ; ​            // This is the test Q. +
-  queue_init(&​testQ,​ PUSH_POP_Q_SIZE, ​ PUSH_POP_Q_NAME); ​ // Init the test Q. +
-  // Test queue_empty(). +
-  tempResult = queue_empty(&​testQ);​ +
-  if (!tempResult) { +
-    printf("​Error: queue_empty(%s) should return true but returned false.\n\r"​queue_name(&​testQ)); +
-  } +
-  testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-  // Run the loop below until you have used up all of the values in the nonCircularQ. +
-  // Each run of the loop will cause some number of pushes and pops to occur. +
-  // The loop runs until all values of the nonCircularQ have been pushed, and +
-  // all values in the push-pop Q are pop'​d. +
-  do { +
-    // Make sure not to push too much into testQ, or to go beyond the bounds of the nonCircularQ. +
-    uint16_t spaceInTestQ = queue_size(&​testQ) - queue_elementCount(&​testQ); ​   // Size left in testQ. +
-    uint16_t ncqUnusedValues = NON_CIRC_Q_SIZE - 1 - ncqPushIndexPtr; ​ // Unused values in noncircularQ. +
-    uint16_t pushCount = rand() % MAX_PUSH_POP_COUNT; ​       // Compute a base number of pops. +
-    // Potentially reduce push-count to available space in testQ +
-    pushCount = pushCount <= spaceInTestQ ? pushCount : spaceInTestQ;​ +
-    // Potentially reduce pushCount to remaining values in noncircularQ. +
-    pushCount = pushCount <= ncqUnusedValues ? pushCount : ncqUnusedValues;​ +
-#ifdef QUEUE_PRINT_INFO_MESSAGES +
-    printf("​push-count:​%d\n\r",​ pushCount);​ +
-#endif +
-    for (uint16_t i=0; i<​pushCount;​ i++) { +
-      queue_push(&​testQ,​ ncq[ncqPushIndexPtr++]);​ +
-    } +
-    // Number of elements in the simulated non-circular queue that +
-    // are currently stored in the testQ. +
-    uint16_t simQElementCount = ncqPushIndexPtr - ncqPopIndexPtr;​ +
-    if (queue_elementCount(&​testQ) != simQElementCount) { +
-      printf("​* Error: queue_elementCount(%s) returned %ld should be %d\n\r.",​ queue_name(&​testQ),​ +
-          queue_elementCount(&​testQ),​ simQElementCount);​ +
-      tempResult = false; +
-      break; ​ // This needs to be fixed before proceeding further. +
-    } +
-    // Don't pop more than you have pushed. +
-    uint16_t popCount = rand() % MAX_PUSH_POP_COUNT;​ +
-    // set popCount to be no more that the current simQElementCount (don't overrun the non-circular queue). +
-    popCount = simQElementCount >= popCount ? popCount : simQElementCount;​ +
-#ifdef QUEUE_PRINT_INFO_MESSAGES +
-    printf("​pop-count:​%d\n\r",​ popCount);​ +
-#endif +
-    // Check each pop'd value for correctness. +
-    double temp; +
-    for (uint16_t i=0; i<​popCount;​ i++) {  // Iterate over the pop'd values. +
-      if ((temp=queue_pop(&​testQ)) != ncq[ncqPopIndexPtr]) {  // Should match the non-circular queue. +
-        printf("​* Error: queue_pop(%s) returned %lf, should be %lf", queue_name(&​testQ),​ temp, ncq[ncqPopIndexPtr]);​ +
-        tempResult = false; +
-      } +
-      ncqPopIndexPtr++;​ +
-    } +
-    // Keep going until all values contained in the non-circular queue are exhausted. +
-  } while((ncqPushIndexPtr != ncqPopIndexPtr) || (ncqPushIndexPtr != NON_CIRC_Q_SIZE-1));​ +
-  testResult = tempResult ? testResult : false; +
-  return testResult;+
 } }
  
-// Checks to see that underflow and overflow work, and that error messages are printed. +// Returns ​count of the elements ​currently contained in the queue. 
-#define ERROR_CONDITION_Q_SIZE 10 +queue_size_t queue_elementCount(queue_t ​*q
-#define ERROR_CONDITION_Q_NAME "​errorQ"​ +
-bool queue_testErrorConditions() { + return ​q->​elementCount;
-  bool tempResult = true;  // Local test results. +
-  bool testResult = true;  // Overall test results. +
-  // A queue for testing. +
-  queue_t testQ; +
-  queue_init(&​testQ,​ ERROR_CONDITION_Q_SIZE,​ ERROR_CONDITION_Q_NAME);​ +
-  // See that the empty function works correctly. +
-  tempResult = queue_empty(&​testQ);​ +
-  if (!tempResult) { +
-    printf("​* Error: queue_empty(%s) returned false, should be true.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = tempResult ? testResult : false; +
-  // pop an element from the empty queue and check for underflow. +
-  printf("​=== + User code should print queue empty error message->​ "); +
-  // Check for underflow by popping an empty queue. +
-  queue_pop(&​testQ);​ +
-  tempResult = queue_underflow(&​testQ);​ +
-  if (!tempResult) { +
-    printf("​* Error: queue_underflow(%s) returned false, should be true.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = tempResult ? testResult : false; +
-  // Fill up the queue with one too many elements+
-  printf("​=== + User code should print a queue full error message->​ "); +
-  for (uint16_t i=0; i<​ERROR_CONDITION_Q_SIZE+1;​ i++) { +
-    queue_push(&​testQ,​ 0.0); +
-  } +
-  // Check for overflow should be true. +
-  tempResult = queue_overflow(&​testQ);​ +
-  if (!tempResult) { +
-    printf("​* Error: queue_overflow(%s) returned false, should be true.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = tempResult ? testResult : false; +
-  // underflow flag should have been cleared with the first push, should return false. +
-  tempResult = queue_underflow(&​testQ);​ +
-  if (tempResult) { +
-    printf("​* Error: queue_underflow(%s) returned true, should be false.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = !tempResult ? testResult : false; +
-  // Check to see that the queue is full+
-  ​tempResult = queue_full(&​testQ);​ +
-  if (!tempResult) { +
-    printf("​Error: queue_full(%sreturned false, should be true.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = tempResult ? testResult : false; +
-  // Calling queue_pop() should clear the overflow flag. +
-  queue_pop(&​testQ);​ +
-  tempResult = queue_overflow(&​testQ);​ +
-  if (tempResult) ​+
-    ​printf("​** Error: queue_overflow(%s) returned true, should be false.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = !tempResult ? testResult : false; +
-  // Check to see that the queue is no longer full after one pop. +
-  tempResult = queue_full(&​testQ);​ +
-  if (tempResult) { +
-    printf("​* Error: queue_full(%s) returned true, should be false.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = !tempResult ? testResult : false; +
-  // underflow flag should also be false at this point. +
-  tempResult = queue_underflow(&​testQ);​ +
-  if (tempResult) { +
-    printf("​* Error: queue_underflow(%s) returned true, should be false.\n\r",​ queue_name(&​testQ));​ +
-  } +
-  testResult = !tempResult ? testResult : false; +
-  queue_garbageCollect(&​testQ);​ +
-  ​return ​testResult;+
 } }
  
-// Checks to see that queue_overwritePush() works correctly. +// Returns true if an underflow has occurred (queue_pop() called on an empty 
-// Simple test: just overwritePushes one set of values, and then another. +// queue)
-// Checks to see that contents are correct afterwards. +bool queue_underflow(queue_t *q
-#define OVERWRITE_PUSH_TEST_QUEUE_SIZE 100  // tested ​queue will be this big. +
-#define OVERWRITE_PUSH_TEST_QUEUE_NAME "​overwriteQ" ​ // tested queue will be this big+ return ​q->​underflowFlag;
-bool queue_overwritePushTest() { +
-  bool testResult = true;  // Keep track of overall test results. +
-  // Build a queue for testing. +
-  ​queue_t ​testQ; +
-  queue_init(&​testQ,​ OVERWRITE_PUSH_TEST_QUEUE_SIZE,​ OVERWRITE_PUSH_TEST_QUEUE_NAME);​ +
-  // Allocate two arrays of test data. +
-  double* dataArray1 = (double ​*) malloc((OVERWRITE_PUSH_TEST_QUEUE_SIZE) * sizeof(double));​ +
-  for (uint16_t i=0; i<​OVERWRITE_PUSH_TEST_QUEUE_SIZE;​ i++) +
-    dataArray1[i] = (double) rand(); +
-  double* dataArray2 = (double *) malloc((OVERWRITE_PUSH_TEST_QUEUE_SIZE) * sizeof(double));​ +
-  for (uint16_t i=0; i<​OVERWRITE_PUSH_TEST_QUEUE_SIZE;​ i++) +
-    dataArray2[i] = (double) rand(); +
-  // Fill the queue with all data values. +
-  for (uint16_t i=0; i<​OVERWRITE_PUSH_TEST_QUEUE_SIZE;​ i++) +
-    ​queue_overwritePush(&​testQ,​ dataArray1[i]);​ +
-  } +
-  for (uint16_t i=0; i<​OVERWRITE_PUSH_TEST_QUEUE_SIZE;​ i++) { +
-    queue_overwritePush(&​testQ,​ dataArray2[i]);​ +
-  } +
-  // All that should remain are values from dataArray2. +
-  for (uint16_t i=0; i<​OVERWRITE_PUSH_TEST_QUEUE_SIZE;​ i++) { +
-    if (queue_readElementAt(&​testQ,​ i) != dataArray2[i]) {  // Are the correct values returned from the queue? +
-      printf("​* Error: the values read from the queue: %s are incorrect after queue_overwritePush().\n\r",​ queue_name(&​testQ));​ +
-      testResult = false; +
-      break; +
-    } +
-  } +
-  // Garbage collect all of the allocated memory. +
-  queue_garbageCollect(&​testQ);​ +
-  free(dataArray1);​ +
-  free(dataArray2);​ +
-  ​return ​testResult;+
 } }
  
-// Returns true if test passed, false otherwise. +// Returns true if an overflow has occurred ​(queue_push() ​called on a full 
-// This test will build a queue of random size between 10,000 and 20,000 elements, and: +// queue). 
-// 1. Create a same-sized array to contain random values to store in the queue. +bool queue_overflow(queue_t ​*q
-// 2. Fill the queue with the random values and from the array and then check for full. +
-// 3. Test to see that queue_readElementAt() works correctly. + return q->​overflowFlag;
-// 3. Pop each of the values (checking to see that the correct values are pop'd and then check for empty. +
-// 4. Test the queue by interspersing pushes and pops in the same queue. +
-// 5. Refill the array with the previous random values. +
-// 6. Use queue_overwritePush() to write over all of the elements of the array, checking the contents. +
-#define QUEUE_TEST_MAX_QUEUE_SIZE 100  // Used for the fill/empty tests. +
-#define QUEUE_TEST_MAX_LOOP_COUNT 10   // All tests will be invoked this many times. +
-#define QUEUE_TEST_QUEUE_NAME "​test_queue"​ +
-bool queue_runTest() { +
-  bool testResult = true;  // Be optimistic. +
-  // Overall test will be executed QUEUE_TEST_MAX_LOOP_COUNT times. +
-  for (uint32_t loopCount = 0; loopCount<​QUEUE_TEST_MAX_LOOP_COUNT;​ loopCount++) { +
-    printf("​=== Queue Test Iteration %ld ===\n\r",​ loopCount);​ +
-    // Compute the size of the data set randomly within given bounds. +
-    uint32_t arraySize = (rand() % (QUEUE_TEST_MAX_QUEUE_SIZE/​2)) + (QUEUE_TEST_MAX_QUEUE_SIZE/​2);​ +
-    printf("​=== Commencing basic fill test (calling ​queue_push() ​until full) of queue of size: %ld. === \n\r", arraySize); +
-    // Allocate the array. +
-    double* dataArray = (queue_data_t *) malloc(sizeof(queue_data_t) * arraySize);​ +
-    for (uint32_t i=0; i<​arraySize;​ i++) { +
-      dataArray[i] = (double) rand(); +
-    } +
-    queue_t testQ;  ​// queue instance used for testing. +
-    queue_init(&​testQ,​ arraySize, QUEUE_TEST_QUEUE_NAME);  // Init the queue+
-    ​testResult = queue_fillTest(&​testQ,​ dataArray, arraySize) ? testResult : false; +
-    if (testResult) { +
-      printf("​=== Queue: %s passed a basic fill test.\n\r",​ queue_name(&​testQ));​ +
-    } else { +
-      printf("​=== Queue: %s failed a basic fill test.\n\r",​ queue_name(&​testQ));​ +
-    } +
-    if (queue_elementCount(&​testQ) != arraySize) { +
-      printf("​* Error: queue_elementCount(%s) is %ld, should be %ld\n\r",​ queue_name(&​testQ),​ queue_elementCount(&​testQ),​ arraySize);​ +
-      printf("​* Error: queue_elementCount() likely has a bug.\n\r"​);​ +
-      testResult = false; +
-    } +
-    // Run the queue-empty test. +
-    printf("​=== Commencing basic empty test (calling queue_pop() until empty) === \n\r"​);​ +
-    ​bool tempResult = queue_emptyTest(&testQ, dataArray, arraySize);​ +
-    if (tempResult) { +
-      printf("​=== Queue: %s passed a basic empty test.\n\r",​ queue_name(&​testQ));​ +
-    } else { +
-      printf("​=== Queue: %s failed a basic empty test.\n\r",​ queue_name(&​testQ));​ +
-    } +
-    testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-    tempResult = true; +
-    if (queue_elementCount(&​testQ) != 0) { +
-      printf("​Error: queue_elementCount(%sis %ld, should be %d\n\r",​ queue_name(&​testQ),​ queue_elementCount(&​testQ),​ 0); +
-      ​printf("​* Error: queue_elementCount() likely has a bug.\n\r"​);​ +
-      tempResult = false; +
-    } +
-    // Run the push/pop test. +
-    printf("​=== Commencing push/pop test.) === \n\r"​);​ +
-    tempResult = queue_pushPopTest();​ +
-    if (tempResult) ​+
-      ​printf("​=== Queue: %s passed a push/pop test.\n\r",​ queue_name(&​testQ));​ +
-    } else { +
-      printf("​=== Queue: %s failed a push/pop test.\n\r",​ queue_name(&​testQ));​ +
-    } +
-    testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-    printf("​=== Commencing error-condition test (calling queue_pop() until empty) === \n\r"​);​ +
-    tempResult = queue_testErrorConditions();​ +
-    if (tempResult) { +
-      printf("​=== Queue: %s passed error-condition test.\n\r",​ queue_name(&​testQ));​ +
-    } else { +
-      printf("​=== Queue: %s failed error-condition test.\n\r",​ queue_name(&​testQ));​ +
-    } +
-    testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-    printf("​=== Commencing overwritePush test (calling queue_pop() until empty) === \n\r"​);​ +
-    tempResult = queue_overwritePushTest();​ +
-    if (tempResult) { +
-      printf("​=== Queue: %s passed overwritePush test.\n\r",​ queue_name(&​testQ));​ +
-    } else { +
-      printf("​=== Queue: %s failed overwritePush test.\n\r",​ queue_name(&​testQ));​ +
-    } +
-    testResult = tempResult ? testResult : false; ​ // Logical AND of testResult and tempResult. +
-    if (testResult) { +
-      printf("​=== All queue tests passed. ===\n\r\n\r"​);​ +
-    } else { +
-      printf("​=== Some queue tests failed. Look at informational messages.\n\r\n\r"​);​ +
-    } +
-    // All done. Free up all allocated memory. +
-    queue_garbageCollect(&​testQ);​ +
-    free(dataArray);​ +
-  } +
-  return testResult;+
 } }
  
 +// Frees the storage that you malloc'​d before.
 +void queue_garbageCollect(queue_t *q)
 +{
 + free(q->​data);​
 +}
 </​file>​ </​file>​
  
 ---- ----
  
queue_resources.1673299484.txt.gz · Last modified: 2023/01/09 14:24 by scott