Skip to content

Commit

Permalink
Section rework wip
Browse files Browse the repository at this point in the history
  • Loading branch information
BlockoS committed Nov 4, 2024
1 parent 352e370 commit 1c0a06a
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 6 deletions.
124 changes: 124 additions & 0 deletions section.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,127 @@ void section_delete(Section *ptr, int n) {
}
free(ptr);
}

// Reset a section array.
void section_array_reset(SectionArray *arr) {
assert(arr != NULL);
if(arr->data != NULL) {
for(size_t i=0; i<arr->count; i++) {
free(arr->data[i].name);
free(arr->data[i].output);
free(arr->data[i].description);
section_reset(&arr->data[i]);
}
}
arr->count = 0;
}

// Release section array memory.
void section_array_delete(SectionArray *arr) {
assert(arr != NULL);
section_array_reset(arr);
free(arr->data);
arr->data = NULL;
arr->capacity = 0;
}

// Check if 2 sections overlaps.
// \return 1 Both sections has the same time and overlaps
// \return 0 Sections don't overlap
// \return -1 Sections overlap but they are not of the same type.
static int section_overlap(const Section *a, const Section *b) {
assert(a != NULL);
assert(b != NULL);

int ret = 0;

if(a->page == b->page) {
if(a->logical > b->logical) {
const Section *tmp = b;
b = a;
a = tmp;
}
if(b->logical <= (a->logical + a->size)) {
if(a->type == b->type) {
ret = 1;
} else {
ret = -1;
}
}
}
return ret;
}

static inline uint16_t minu16(uint16_t a, uint16_t b) {
return (a < b) ? a : b;
}

static inline uint16_t maxi32(int32_t a, int32_t b) {
return (a > b) ? a : b;
}

// Merge 2 sections the 2nd section into the 1st one.
static void section_merge(Section *a, const Section *b) {
assert(a != NULL);
assert(b != NULL);

uint16_t begin = minu16(a->logical, b->logical);
int32_t end = maxi32(a->logical+a->size, b->logical+b->size);
a->logical = begin;
a->size = end - begin;
}

// Add a new section.
int section_array_add(SectionArray *arr, const Section* in) {
assert(arr != NULL);
assert(in != NULL);

int ret = -1;//todo
size_t i;
// Search for overlapping section.
for(i=0; i<arr->count; i++) {
int overlap = section_overlap(&arr->data[i], in);
if(overlap == 1) {
section_merge(&arr->data[i], in);
INFO_MSG("Section %s has been merged with %s!", arr->data[i].name, in->name);
break;
} else if(overlap == -1) {
WARNING_MSG("Section %s and %s overlaps! %x %x.%x", arr->data[i].name, in->name);
break;
}
}

if(i >= arr->count) {
// Check if we need to expand section array buffer
if(i >= arr->capacity) {
size_t n = arr->capacity + 4U;
Section *ptr = realloc(arr->data, n*sizeof(Section));
if(ptr == NULL) {
ERROR_MSG("Failed to expand section array buffer", strerror(errno));
} else {
arr->data = ptr;
arr->capacity = n;
ret = true;
}
} else {
ret = true;
}

// Append new section.
if(ret) {
arr->data[arr->count++] = *in;
}
}
return ret;
}

// Retrieve the ith section from the array.
const Section* section_array_get(SectionArray *arr, size_t i) {
const Section *ret = NULL;
if(arr != NULL) {
if((arr->data != NULL) && (i < arr->count)) {
ret = &arr->data[i];
}
}
return ret;
}
42 changes: 38 additions & 4 deletions section.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,59 @@ void section_reset(Section *s);
/// Group section per output filename and sort them in page/logical address order.
/// \param [in out] ptr Sections.
/// \param [in] n Number of sections to sort.
void section_sort(Section *ptr, size_t n);
void section_sort(Section *ptr, size_t n); // [todo] will be removed

/// Delete sections.
void section_delete(Section *ptr, int n);
void section_delete(Section *ptr, int n); // [todo] will be removed

// Load sections from a JSON file.
// \param [out] out Loaded sections.
// \param [out] n Number of loaded sections.
// \param [in] filename Input filename.
// \return true if the sections contained in the file were succesfully loaded.
// \return false if an error occured.
bool section_load(Section **out, int *n, const char *filename);
bool section_load(Section **out, int *n, const char *filename); // [todo] use SectionArray

// Save sections to a JSON file.
// \param [in] ptr Sections to be saved.
// \param [in] count Number of sections.
// \param [in] filename Output filename.
// \return true if the sections were succesfully saved.
// \return false if an error occured.
bool section_save(const Section *ptr, int n, const char *filename);
bool section_save(const Section *ptr, int n, const char *filename); // [todo] use SectionArray

// Section array
typedef struct {
Section *data; ///< Pointer to section array.
size_t count; ///< Number of sections currently in use.
size_t capacity; ///< Number the section array can hold.
// [todo] index array of sorted sections ?
} SectionArray;

/// Reset a section array.
/// \note The internal data pointer will not be freed.
/// \param [in out] arr Section array to be reseted.
void section_array_reset(SectionArray *arr);

/// Release section array memory.
/// \param [in out] arr Section array.
void section_array_delete(SectionArray *arr);

/// Add a new section.
/// Note that if the section overlaps an already existing one, it will be merged if both sections have the
/// same type.
/// \param [in out] arr Section array the section will be added to.
/// \param [in] in Section that will be added to the section array.
/// \return 1 if the section was succesfully added.
/// \return 0 if the section was merged with one from the section array.
/// \return -1 if the section can not be merged or if there is not enough memory to add a new one.
int section_array_add(SectionArray *arr, const Section* in);

/// Retrieve the ith section from the array.
/// \param [in] arr Section array.
/// \param [in] i Index of the section to be retrieved.
/// \return A pointer to the section if the index is within the section array bounds.
/// \return NULL if the index is out of the section array bounds.
const Section* section_array_get(SectionArray *arr, size_t i);

#endif // ETRIPATOR_SECTION_H
1 change: 0 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ add_unit_test(
NAME section
SOURCES
section.c
${PROJECT_SOURCE_DIR}/section.c
${PROJECT_SOURCE_DIR}/section/load.c
${PROJECT_SOURCE_DIR}/message.c
${PROJECT_SOURCE_DIR}/jsonhelpers.c
Expand Down
52 changes: 51 additions & 1 deletion test/section.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
*/
#include <munit.h>
#include "section.h"
#include "../section.c"
#include "message.h"
#include "message/console.h"

Expand Down Expand Up @@ -175,9 +175,59 @@ MunitResult section_load_test(const MunitParameter params[], void* fixture) {
return MUNIT_OK;
}

MunitResult section_overlap_test(const MunitParameter params[], void* fixture) {
Section a = {
.type = SECTION_TYPE_CODE,
.page = 0x01,
};
Section b = {
.type = SECTION_TYPE_CODE,
.page = 0x01,
};

a.logical = 0xe000;
a.size = 0x100;

b.logical = 0xe010;
b.size = 0x40;

munit_assert_int(section_overlap(&a, &b), ==, 1);

b.type = SECTION_TYPE_DATA;
munit_assert_int(section_overlap(&a, &b), ==, -1);

a.type = SECTION_TYPE_DATA;
a.logical = 0x0200;
a.size = 0x10;

b.logical = 0x01e0;
b.size = 0x50;

munit_assert_int(section_overlap(&a, &b), ==, 1);

b.page = 0x02;
munit_assert_int(section_overlap(&a, &b), ==, 0);

b.page = a.page;
b.size = 0x01;
munit_assert_int(section_overlap(&a, &b), ==, 0);

return MUNIT_OK;
}


MunitResult section_add_test(const MunitParameter params[], void* fixture) {
// [todo] add sections
// [todo] add one that merge
// [todo] add one with merge+error
return MUNIT_OK;
}

static MunitTest section_tests[] = {
{ "/sort", section_sort_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ "/load", section_load_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ "/overlap", section_overlap_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ "/add", section_add_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};

Expand Down

0 comments on commit 1c0a06a

Please sign in to comment.