Skip to content

Commit

Permalink
Implement MISRA compliant insertion sort
Browse files Browse the repository at this point in the history
- MISRA compliant insertion sort
  • Loading branch information
jciberlin authored and Igor-Misic committed Mar 15, 2024
1 parent 0d7e623 commit 2030de7
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 0 deletions.
60 changes: 60 additions & 0 deletions Inc/sort/insertion_sort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/****************************************************************************
*
* Copyright (c) 2024 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <jciberlin1@gmail.com>
*
* 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 IMProject 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 OWNER 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.
*
****************************************************************************/

#ifndef UTILITY_INSERTION_SORT_H_
#define UTILITY_INSERTION_SORT_H_

#include "typedefs.h"

#define MAX_ELEMENT_SIZE (64)

/**
* @brief Sort elements using insertion sort algorithm. Insertion sort algorithm is a simple
* sorting algorithm that has O(N^2) time complexity. It is efficient on smaller lists, and
* much less efficient on large lists.
*
* NOTE: implemented that the max element size is 64 B. If element size is larger, then
* MAX_ELEMENT_SIZE macro must be updated.
*
* @param[in/out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in] number_of_elements Number of elements in the buffer.
* @param[in] element_size Size of the element, in bytes.
* @param[in] *compareFun Pointer to compare function. Compare function has two parameters (pointer to
* first element and pointer to second element). As a result, it returns boolean,
* true if first element is greater than second element, otherwise false.
*/
void InsertionSort_sort(byte_t* buffer, int32_t number_of_elements, int32_t element_size,
bool (*compareFun)(void* first, void* second));

#endif /* UTILITY_INSERTION_SORT_H_ */
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ IMUTILITY_FILES=\
Src/crc/crc32_variants/crc32_xfer.c \
Src/sort/bubble_sort.c \
Src/sort/heap_sort.c \
Src/sort/insertion_sort.c \
Src/sort/selection_sort.c \
Src/json.c \
Src/map.c \
Expand All @@ -127,6 +128,7 @@ SRC_FILES+=$(IMUTILITY_FILES) \
Tests/test_crc16.c \
Tests/test_crc32.c \
Tests/test_heap_sort.c \
Tests/test_insertion_sort.c \
Tests/test_json.c \
Tests/test_map.c \
Tests/test_priority_queue.c \
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
### Heap sort
- HeapSort_sort

### Insertion sort
- InsertionSort_sort

### JSON
- Json_startString
- Json_addData
Expand Down
70 changes: 70 additions & 0 deletions Src/sort/insertion_sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/****************************************************************************
*
* Copyright (c) 2024 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <jciberlin1@gmail.com>
*
* 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 IMProject 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 OWNER 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 "sort/insertion_sort.h"

#include <string.h>

void
InsertionSort_sort(byte_t* buffer, int32_t number_of_elements, int32_t element_size,
bool (*compareFun)(void* first, void* second)) {
byte_t* elements = buffer;
static byte_t max_element[MAX_ELEMENT_SIZE];
byte_t* element = &max_element[0];

for (int32_t i = 1; i < number_of_elements; ++i) {
/* -E> compliant MC3R1.R21.18 4 Buffer overflow will not happen, all elements in buffer
* have same size, and their size is stored in element_size variable. Precondition is that
* element_size must be less than or equal to MAX_ELEMENT_SIZE. */
// cppcheck-suppress misra-c2012-17.7; return value is not needed in this case
memcpy(element, &elements[i * element_size], (size_t)element_size);

int32_t j = i - 1;
bool compare = compareFun(&elements[j * element_size], element);

while ((j >= 0) && compare) {
/* -E> compliant MC3R1.R19.1 3 Overlap will not happen, all elements in buffer
* have same size, and their size is stored in element_size variable. */
// cppcheck-suppress misra-c2012-17.7; return value is not needed in this case
memcpy(&elements[(j + 1) * element_size], &elements[j * element_size], (size_t)element_size);
--j;
compare = compareFun(&elements[j * element_size], element);
}
/* -E> compliant MC3R1.R21.18 4 Buffer overflow will not happen, all elements in buffer
* have same size, and their size is stored in element_size variable. Precondition is that
* element_size must be less than or equal to MAX_ELEMENT_SIZE. */
// cppcheck-suppress misra-c2012-17.7; return value is not needed in this case
memcpy(&elements[(j + 1) * element_size], element, (size_t)element_size);
}
}
56 changes: 56 additions & 0 deletions Tests/test_insertion_sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "sort/insertion_sort.h"

#include "unity.h"
#include "unity_fixture.h"

#include "helper/sort_functions.h"

TEST_GROUP(InsertionSort);

TEST_SETUP(InsertionSort) {
}

TEST_TEAR_DOWN(InsertionSort) {
}

TEST_GROUP_RUNNER(InsertionSort) {
RUN_TEST_CASE(InsertionSort, InsertionSort_int32);
RUN_TEST_CASE(InsertionSort, InsertionSort_float64);
RUN_TEST_CASE(InsertionSort, InsertionSort_uint64);
}

TEST(InsertionSort, InsertionSort_int32) {
int32_t unsorted_array[] = {5, 2, 3, 1000000, 9, 10, 11, 8, 9, 100};
const int32_t sorted_array[] = {2, 3, 5, 8, 9, 9, 10, 11, 100, 1000000};
InsertionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareInt32);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_INT32(sorted_array[i], unsorted_array[i]);
}
}

TEST(InsertionSort, InsertionSort_float64) {
float64_t unsorted_array[] = {5.8, 2.2, 3.1, 1.1, 9.1, 10.3, 11.2, 8.4, 9.2, 100.9};
const float64_t sorted_array[] = {1.1, 2.2, 3.1, 5.8, 8.4, 9.1, 9.2, 10.3, 11.2, 100.9};
InsertionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareFloat64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_DOUBLE(sorted_array[i], unsorted_array[i]);
}
}

TEST(InsertionSort, InsertionSort_uint64) {
uint64_t unsorted_array[] = {1111111U, 55555555U, 44444U, 10000000000000U, 212121U, 1111U, 1U, 2U, 5U, 3U};
const uint64_t sorted_array[] = {1U, 2U, 3U, 5U, 1111U, 44444U, 212121U, 1111111U, 55555555U, 10000000000000U};
InsertionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareUint64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_UINT64(sorted_array[i], unsorted_array[i]);
}
}
1 change: 1 addition & 0 deletions Tests/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ RunAllTests(void) {
RUN_TEST_GROUP(Crc16);
RUN_TEST_GROUP(Crc32);
RUN_TEST_GROUP(HeapSort);
RUN_TEST_GROUP(InsertionSort);
RUN_TEST_GROUP(Json);
RUN_TEST_GROUP(Map);
RUN_TEST_GROUP(PriorityQueue);
Expand Down

0 comments on commit 2030de7

Please sign in to comment.