online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <stdio.h> #include "ring_buffer_unit_test.h" int main() { printf("Running ring buffer unit test...\n"); if (true == RingBuffer_UnitTest()) { return 0; } return 1; }
#ifndef _RING_BUFFER_UNIT_TEST_H_ #define _RING_BUFFER_UNIT_TEST_H_ #include <stdbool.h> /** * Runs a unit test of the RingBuffer. * @return true if the test passed, false if it failed */ bool RingBuffer_UnitTest(void); #endif
#include "ring_buffer.h" #include "ring_buffer_unit_test.h" #include <stdint.h> #include <stdio.h> #include <string.h> #ifdef _WIN32 #include <inttypes.h> #define PASSED "PASSED" #define FAILED "FAILED" #ifdef _WIN64 #define PRI_SIZET PRIu64 #else #define PRI_SIZET PRIu32 #endif #else #define PRI_SIZET "zu" #define PASSED "\x1b[32mPASSED\x1b[0m" #define FAILED "\x1b[31mFAILED\x1b[0m" #endif #define test(expr)(!(expr)) ? (printf(FAILED" at line %u\n", __LINE__), false) : (printf(PASSED"\n"), true) #define test_quiet(expr)(!(expr)) ? (printf(FAILED" at line %u\n", __LINE__), false) : true enum { capacity1 = 10, capacity2 = 100, capacity3 = 500, }; const char guardValue = 0xAB; static bool RingBuffer_Init_ut(); static bool RingBuffer_PutChar_ut(); static bool RingBuffer_ut(RingBuffer* buffer) { printf("Test 0: Checking RingBuffer structure...\n"); printf(" - Check if size of ring buffer structure is reasonable: "); bool result = test(sizeof(*buffer) <= 15 * sizeof(int)); printf("Test 0: %s\n\n", (true == result) ? PASSED : FAILED); return result; } static bool RingBuffer_Init_ut(RingBuffer* buffer, char* data, size_t dataSize) { printf("Test 1: Checking RingBuffer_Init...\n"); printf(" - Initialize ring buffer with memory region with size %"PRI_SIZET": ", dataSize); bool result = test(true == RingBuffer_Init(buffer, data, dataSize)); if(true == result) { printf(" Is empty: "); result &= test(true == RingBuffer_IsEmpty(buffer)); printf(" Length is 0: "); result &= test(0 == RingBuffer_GetLen(buffer)); printf(" Capacity is %"PRI_SIZET": ", dataSize); result &= test(dataSize == RingBuffer_GetCapacity(buffer)); } printf("Test 1: %s\n\n", (true == result) ? PASSED : FAILED); return result; } static bool RingBuffer_PutChar_ut(RingBuffer* buffer, char* data, size_t dataSize) { printf("Test 2: Checking RingBuffer_PutChar...\n"); printf(" - Initialize ring buffer with memory region with size %"PRI_SIZET": ", dataSize); bool result = test(true == RingBuffer_Init(buffer, data, dataSize)); if(true == result) { printf(" Write data into the buffer...\n"); for(size_t j = 0; true == result && j < dataSize; j++) { result &= test_quiet(j == RingBuffer_GetLen(buffer)); result &= test_quiet(true == RingBuffer_PutChar(buffer, j % 0x7f)); result &= test_quiet(false == RingBuffer_IsEmpty(buffer)); if(false == result) { printf(" Writing data no %"PRI_SIZET" produced invalid state (IsEmpty: %c, Length: %"PRI_SIZET", Capacity: %"PRI_SIZET")\n", j, RingBuffer_IsEmpty(buffer) ? 'T' : 'F', RingBuffer_GetLen(buffer), RingBuffer_GetCapacity(buffer)); } } if(true == result) { printf(" Cannot hold more data: "); result &= test(false == RingBuffer_PutChar(buffer, '0')); printf(" Capacity is %"PRI_SIZET": ", dataSize); result &= test(dataSize == RingBuffer_GetCapacity(buffer)); printf(" Length is %"PRI_SIZET": ", dataSize); result &= test(dataSize == RingBuffer_GetLen(buffer)); printf(" Is not empty: "); result &= test(false == RingBuffer_IsEmpty(buffer)); } } printf("Test 2: %s\n\n", (true == result) ? PASSED : FAILED); return result; } static bool RingBuffer_GetChar_ut(RingBuffer* buffer, char* data, size_t dataSize) { printf("Test 3: Checking RingBuffer_GetChar...\n"); printf(" - Initialize ring buffer with memory region with size %"PRI_SIZET": ", dataSize); bool result = test(true == RingBuffer_Init(buffer, data, dataSize)); if(true == result) { printf(" Write data into the buffer...\n"); for(size_t j = 0; true == result && j < dataSize; j++) { result &= test_quiet(true == RingBuffer_PutChar(buffer, j % 0x7f)); if(false == result) { printf(" Writing data no %"PRI_SIZET" produced invalid state (IsEmpty: %c, Length: %"PRI_SIZET", Capacity: %"PRI_SIZET")\n", j, RingBuffer_IsEmpty(buffer) ? 'T' : 'F', RingBuffer_GetLen(buffer), RingBuffer_GetCapacity(buffer)); } } if(true == result) { printf(" Read data from the buffer...\n"); char in ; for(size_t j = 0; true == result && j < dataSize; ++j) { result &= test_quiet(true == RingBuffer_GetChar(buffer, &in)); if(true == result) { result &= test_quiet(j % 0x7f == in); if(false == result) { printf(" Data no %"PRI_SIZET" mismatch (%x, but expected %x)\n", j, (int)in, (int)j % 0x7f); } } else { printf(" Failed to read data no %"PRI_SIZET"\n", j); } } if(true == result) { printf(" Is empty: "); result &= test(true == RingBuffer_IsEmpty(buffer)); printf(" Length is 0: "); result &= test(0 == RingBuffer_GetLen(buffer)); printf(" Capacity is %"PRI_SIZET": ", dataSize); result &= test(dataSize == RingBuffer_GetCapacity(buffer)); printf(" Can be written: "); result &= test(true == RingBuffer_PutChar(buffer, '0')); } } } printf("Test 3: %s\n\n", (true == result) ? PASSED : FAILED); return result; } static bool RingBuffer_Clear_ut(RingBuffer* buffer, char* data, size_t dataSize) { printf("Test 4: Checking RingBuffer_Clear...\n"); printf(" - Initialize ring buffer with memory region with size %"PRI_SIZET": ", dataSize); bool result = test(true == RingBuffer_Init(buffer, data, dataSize)); if(true == result) { printf(" Write data into the buffer...\n"); for(size_t j = 0; true == result && j < dataSize; j++) { result &= test_quiet(true == RingBuffer_PutChar(buffer, j % 0x7f)); if(false == result) { printf(" Writing data no %"PRI_SIZET" produced invalid state (IsEmpty: %c, Length: %"PRI_SIZET", Capacity: %"PRI_SIZET")\n", j, RingBuffer_IsEmpty(buffer) ? 'T' : 'F', RingBuffer_GetLen(buffer), RingBuffer_GetCapacity(buffer)); } } if(true == result) { printf(" Successful Clear: "); result &= test(true == RingBuffer_Clear(buffer)); printf(" Is empty: "); result &= test(true == RingBuffer_IsEmpty(buffer)); printf(" Length is 0: "); result &= test(0 == RingBuffer_GetLen(buffer)); printf(" Capacity is %"PRI_SIZET": ", dataSize); result &= test(dataSize == RingBuffer_GetCapacity(buffer)); printf(" Can be written: "); result &= test(true == RingBuffer_PutChar(buffer, '0')); } } printf("Test 4: %s\n\n", (true == result) ? PASSED : FAILED); return result; } static bool RingBuffer_Interleaved_ut(RingBuffer* buffer, char* data, size_t dataSize) { printf("Test 5: Checking RingBuffer interleaved read/write...\n"); printf(" - Initialize guard memory region...\n"); data[0] = data[dataSize - 1] = guardValue; size_t dataSizeWithoutGuard = dataSize -2; printf(" - Initialize ring buffer with memory region with size %"PRI_SIZET": ", dataSizeWithoutGuard); bool result = test(true == RingBuffer_Init(buffer, data + 1, dataSizeWithoutGuard)); if(true == result) { printf(" Write data into the buffer...\n"); for(size_t j = 0; true == result && j < dataSizeWithoutGuard; ++j) { result &= test_quiet(j == RingBuffer_GetLen(buffer)); result &= test_quiet(true == RingBuffer_PutChar(buffer, 0xFF)); } if(true == result) { for(size_t j = 0; true == result && j < 10; ++j) { printf(" Read data from the buffer...\n"); char in; for(size_t j = 0; true == result && j < dataSizeWithoutGuard/2; ++j) { result &= test_quiet(true == RingBuffer_GetChar(buffer, &in)); if(true == result) { result &= test_quiet((char)0xFF == in); } } if(true == result) { printf(" Write data into the buffer...\n"); for(size_t j = 0; true == result && j < dataSizeWithoutGuard/2; ++j) { if(result &= test_quiet(true == RingBuffer_PutChar(buffer, 0xFF))) { if(false == (result &= test_quiet(guardValue == data[0] && guardValue == data[dataSize - 1]))) { printf(" Writing data resulted in Buffer Overflow\n"); } } } } } } } printf("Test 5: %s\n\n", (true == result) ? PASSED : FAILED); return result; } bool RingBuffer_UnitTest(void) { RingBuffer buffer; char data1[capacity1], data2[capacity2], data3[capacity3]; char* data[] = {data1, data2, data3}; size_t dataSize[] = { sizeof(data1), sizeof(data2), sizeof(data3)}; bool result = true; for(int i = 0; true == result && i < sizeof(data)/ sizeof(*data); ++i) { printf("========== PERFORMING TEST FOR DATA BUFFER WITH SIZE %"PRI_SIZET" ==========\n", dataSize[i]); do { if(false == (result &= RingBuffer_ut(&buffer))) break; if(false == (result &= RingBuffer_Init_ut(&buffer, data[i], dataSize[i]))) break; if(false == (result &= RingBuffer_PutChar_ut(&buffer, data[i], dataSize[i]))) break; if(false == (result &= RingBuffer_GetChar_ut(&buffer, data[i], dataSize[i]))) break; if(false == (result &= RingBuffer_Clear_ut(&buffer, data[i], dataSize[i]))) break; if(false == (result &= RingBuffer_Interleaved_ut(&buffer, data[i], dataSize[i]))) break; } while(0); printf("========== TEST FOR DATA BUFFER WITH SIZE %"PRI_SIZET" FINISHED WITH RESULT %s ==========\n", dataSize[i], (true == result) ? PASSED : FAILED); } return result; }
#ifndef _RING_BUFFER_ #define _RING_BUFFER_ #include <stdint.h> #include <stdbool.h> #include <stddef.h> #include <string.h> char buffer[]; /** Structure describing the ring buffer. */ typedef struct { char * buf; // pointer size_t len; // length buffer uint32_t head; // head pointer value uint32_t tail; // tail pointer value size_t size; // tail pointer value } RingBuffer; /** * Initializes the given ring buffer structure. * * @param ringBuffer pointer to a \ref RingBuffer structure * @param dataBuffer pointer to a location in memory, where the ring buffer data will be stored * @param dataBufferSize size in bytes of the dataBuffer * @return true if all arguments are valid and the ring buffer is initialized successfully, false otherwise */ bool RingBuffer_Init(RingBuffer *ringBuffer, char *dataBuffer, size_t dataBufferSize); /** * Clears contents of the given ring buffer. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return true if the ring buffer is cleared successfully, false otherwise */ bool RingBuffer_Clear(RingBuffer *ringBuffer); /** * Checks if the given ring buffer is empty. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return true if the ring buffer holds no data, false otherwise */ bool RingBuffer_IsEmpty(const RingBuffer *ringBuffer); /** * Gets the length (in bytes) of the data stored in the given ring buffer. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return length (in bytes) of the data stored in the ring buffer */ size_t RingBuffer_GetLen(const RingBuffer *ringBuffer); /** * Returns the capacity (in bytes) of the given buffer. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return capacity (in bytes) of the ring buffer (how much characters can it store) */ size_t RingBuffer_GetCapacity(const RingBuffer *ringBuffer); /** * Appends a single character to the ring buffer. The stored data length will be * increased by 1. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return true if the character was added successfully, false otherwise */ bool RingBuffer_PutChar(RingBuffer *ringBuffer, char c); /** * Pulls out a single character from the ring buffer. The stored data length will be * decreased by 1. * * @param ringBuffer pointer to a \ref RingBuffer structure * @return true if the character was pulled out successfully, false otherwise */ bool RingBuffer_GetChar(RingBuffer *ringBuffer, char *c); #endif //_RING_BUFFER_
/* Includes ------------------------------------------------------------------*/ #include <assert.h> #include "ring_buffer.h" bool RingBuffer_Init(RingBuffer *ringBuffer, char *dataBuffer, size_t dataBufferSize) { assert(ringBuffer); assert(dataBuffer); assert(dataBufferSize > 0); if ((ringBuffer) && (dataBuffer) && (dataBufferSize > 0)) { ringBuffer->head = 0; ringBuffer->tail = 0; ringBuffer->len = 0; ringBuffer->size = dataBufferSize; ringBuffer->buf = dataBuffer; return true; } return false; } bool RingBuffer_Clear(RingBuffer *ringBuffer) { assert(ringBuffer); if (ringBuffer) { memset(ringBuffer->buf, 0, ringBuffer->size); ringBuffer->head = 0; ringBuffer->tail = 0; ringBuffer->len = 0; return true; } return false; } bool RingBuffer_IsEmpty(const RingBuffer *ringBuffer) { assert(ringBuffer); // Sprawdzamy czy w buforze jest coś do odczytania if (ringBuffer->head == ringBuffer->tail) return true; else return false; } size_t RingBuffer_GetLen(const RingBuffer *ringBuffer) { assert(ringBuffer); if (ringBuffer) { // TODO size_t dataLen = ringBuffer->len; return dataLen; } return 0; } size_t RingBuffer_GetCapacity(const RingBuffer *ringBuffer) { assert(ringBuffer); if (ringBuffer) { // TODO size_t dataLen = ringBuffer->len; size_t dataSize = ringBuffer->size; size_t cap = dataSize-dataLen; return cap; } return 0; } bool RingBuffer_PutChar(RingBuffer *ringBuffer, char c) { assert(ringBuffer); if (ringBuffer) { uint32_t head_temp = ringBuffer->head + 1; // Przypisujemy do zmiennej następny indeks head size_t cap = RingBuffer_GetCapacity(ringBuffer); //if(head_temp != ringBuffer->tail) // jesli bufor nie jest pusty // // Jeśli był to ostatni element tablicy to ustawiamy wskaźnik na jej początek //if ( head_temp == ringBuffer->size ) // head_temp = 0; // if ((ringBuffer->len)<(ringBuffer->size)) // jesli bufor nie jest przepelniony if (cap) // jesli jest miejsce w buforze { // Jeśli jest miejsce w buforze to przechodzimy dalej: ringBuffer->buf[head_temp] = c; // Wpisujemy wartość do bufora ringBuffer->head = head_temp; // Zapisujemy nowy indeks head ringBuffer->len++; // = ringBuffer->len + 1; return true; } // Sprawdzamy czy jest miejsce w buforze. // Jeśli bufor jest pełny to wychodzimy z funkcji i zwracamy błąd. //if ( head_temp != ringBuffer->tail ) // Można zamiast tego czekać na zwolnienie miejsca: while (head_temp == q->tail); } return false; } bool RingBuffer_GetChar(RingBuffer *ringBuffer, char *c) { assert(ringBuffer); assert(c); if ((ringBuffer) && (c)) { // TODO // Sprawdzamy czy w buforze jest coś do odczytania // Jeśli bufor jest pusty to wychodzimy z funkcji i zwracamy błąd. if (ringBuffer->head == ringBuffer->tail) return false; // Jeśli jest coś do odczytania to przechodzimy dalej: ringBuffer->tail++; // Inkrementujemy indeks tail // Jeśli był to ostatni element tablicy to ustawiamy wskaźnik na jej początek if (ringBuffer->tail == ringBuffer->size) ringBuffer->tail = 0; *c = ringBuffer->buf[ringBuffer->tail]; // Odczytujemy wartość z bufora } return true; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue