Skip to content

Commit 1c0a06a

Browse files
committed
Section rework wip
1 parent 352e370 commit 1c0a06a

File tree

4 files changed

+213
-6
lines changed

4 files changed

+213
-6
lines changed

section.c

+124
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,127 @@ void section_delete(Section *ptr, int n) {
116116
}
117117
free(ptr);
118118
}
119+
120+
// Reset a section array.
121+
void section_array_reset(SectionArray *arr) {
122+
assert(arr != NULL);
123+
if(arr->data != NULL) {
124+
for(size_t i=0; i<arr->count; i++) {
125+
free(arr->data[i].name);
126+
free(arr->data[i].output);
127+
free(arr->data[i].description);
128+
section_reset(&arr->data[i]);
129+
}
130+
}
131+
arr->count = 0;
132+
}
133+
134+
// Release section array memory.
135+
void section_array_delete(SectionArray *arr) {
136+
assert(arr != NULL);
137+
section_array_reset(arr);
138+
free(arr->data);
139+
arr->data = NULL;
140+
arr->capacity = 0;
141+
}
142+
143+
// Check if 2 sections overlaps.
144+
// \return 1 Both sections has the same time and overlaps
145+
// \return 0 Sections don't overlap
146+
// \return -1 Sections overlap but they are not of the same type.
147+
static int section_overlap(const Section *a, const Section *b) {
148+
assert(a != NULL);
149+
assert(b != NULL);
150+
151+
int ret = 0;
152+
153+
if(a->page == b->page) {
154+
if(a->logical > b->logical) {
155+
const Section *tmp = b;
156+
b = a;
157+
a = tmp;
158+
}
159+
if(b->logical <= (a->logical + a->size)) {
160+
if(a->type == b->type) {
161+
ret = 1;
162+
} else {
163+
ret = -1;
164+
}
165+
}
166+
}
167+
return ret;
168+
}
169+
170+
static inline uint16_t minu16(uint16_t a, uint16_t b) {
171+
return (a < b) ? a : b;
172+
}
173+
174+
static inline uint16_t maxi32(int32_t a, int32_t b) {
175+
return (a > b) ? a : b;
176+
}
177+
178+
// Merge 2 sections the 2nd section into the 1st one.
179+
static void section_merge(Section *a, const Section *b) {
180+
assert(a != NULL);
181+
assert(b != NULL);
182+
183+
uint16_t begin = minu16(a->logical, b->logical);
184+
int32_t end = maxi32(a->logical+a->size, b->logical+b->size);
185+
a->logical = begin;
186+
a->size = end - begin;
187+
}
188+
189+
// Add a new section.
190+
int section_array_add(SectionArray *arr, const Section* in) {
191+
assert(arr != NULL);
192+
assert(in != NULL);
193+
194+
int ret = -1;//todo
195+
size_t i;
196+
// Search for overlapping section.
197+
for(i=0; i<arr->count; i++) {
198+
int overlap = section_overlap(&arr->data[i], in);
199+
if(overlap == 1) {
200+
section_merge(&arr->data[i], in);
201+
INFO_MSG("Section %s has been merged with %s!", arr->data[i].name, in->name);
202+
break;
203+
} else if(overlap == -1) {
204+
WARNING_MSG("Section %s and %s overlaps! %x %x.%x", arr->data[i].name, in->name);
205+
break;
206+
}
207+
}
208+
209+
if(i >= arr->count) {
210+
// Check if we need to expand section array buffer
211+
if(i >= arr->capacity) {
212+
size_t n = arr->capacity + 4U;
213+
Section *ptr = realloc(arr->data, n*sizeof(Section));
214+
if(ptr == NULL) {
215+
ERROR_MSG("Failed to expand section array buffer", strerror(errno));
216+
} else {
217+
arr->data = ptr;
218+
arr->capacity = n;
219+
ret = true;
220+
}
221+
} else {
222+
ret = true;
223+
}
224+
225+
// Append new section.
226+
if(ret) {
227+
arr->data[arr->count++] = *in;
228+
}
229+
}
230+
return ret;
231+
}
232+
233+
// Retrieve the ith section from the array.
234+
const Section* section_array_get(SectionArray *arr, size_t i) {
235+
const Section *ret = NULL;
236+
if(arr != NULL) {
237+
if((arr->data != NULL) && (i < arr->count)) {
238+
ret = &arr->data[i];
239+
}
240+
}
241+
return ret;
242+
}

section.h

+38-4
Original file line numberDiff line numberDiff line change
@@ -99,25 +99,59 @@ void section_reset(Section *s);
9999
/// Group section per output filename and sort them in page/logical address order.
100100
/// \param [in out] ptr Sections.
101101
/// \param [in] n Number of sections to sort.
102-
void section_sort(Section *ptr, size_t n);
102+
void section_sort(Section *ptr, size_t n); // [todo] will be removed
103103

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

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

115115
// Save sections to a JSON file.
116116
// \param [in] ptr Sections to be saved.
117117
// \param [in] count Number of sections.
118118
// \param [in] filename Output filename.
119119
// \return true if the sections were succesfully saved.
120120
// \return false if an error occured.
121-
bool section_save(const Section *ptr, int n, const char *filename);
121+
bool section_save(const Section *ptr, int n, const char *filename); // [todo] use SectionArray
122+
123+
// Section array
124+
typedef struct {
125+
Section *data; ///< Pointer to section array.
126+
size_t count; ///< Number of sections currently in use.
127+
size_t capacity; ///< Number the section array can hold.
128+
// [todo] index array of sorted sections ?
129+
} SectionArray;
130+
131+
/// Reset a section array.
132+
/// \note The internal data pointer will not be freed.
133+
/// \param [in out] arr Section array to be reseted.
134+
void section_array_reset(SectionArray *arr);
135+
136+
/// Release section array memory.
137+
/// \param [in out] arr Section array.
138+
void section_array_delete(SectionArray *arr);
139+
140+
/// Add a new section.
141+
/// Note that if the section overlaps an already existing one, it will be merged if both sections have the
142+
/// same type.
143+
/// \param [in out] arr Section array the section will be added to.
144+
/// \param [in] in Section that will be added to the section array.
145+
/// \return 1 if the section was succesfully added.
146+
/// \return 0 if the section was merged with one from the section array.
147+
/// \return -1 if the section can not be merged or if there is not enough memory to add a new one.
148+
int section_array_add(SectionArray *arr, const Section* in);
149+
150+
/// Retrieve the ith section from the array.
151+
/// \param [in] arr Section array.
152+
/// \param [in] i Index of the section to be retrieved.
153+
/// \return A pointer to the section if the index is within the section array bounds.
154+
/// \return NULL if the index is out of the section array bounds.
155+
const Section* section_array_get(SectionArray *arr, size_t i);
122156

123157
#endif // ETRIPATOR_SECTION_H

test/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ add_unit_test(
128128
NAME section
129129
SOURCES
130130
section.c
131-
${PROJECT_SOURCE_DIR}/section.c
132131
${PROJECT_SOURCE_DIR}/section/load.c
133132
${PROJECT_SOURCE_DIR}/message.c
134133
${PROJECT_SOURCE_DIR}/jsonhelpers.c

test/section.c

+51-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
3535
*/
3636
#include <munit.h>
37-
#include "section.h"
37+
#include "../section.c"
3838
#include "message.h"
3939
#include "message/console.h"
4040

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

178+
MunitResult section_overlap_test(const MunitParameter params[], void* fixture) {
179+
Section a = {
180+
.type = SECTION_TYPE_CODE,
181+
.page = 0x01,
182+
};
183+
Section b = {
184+
.type = SECTION_TYPE_CODE,
185+
.page = 0x01,
186+
};
187+
188+
a.logical = 0xe000;
189+
a.size = 0x100;
190+
191+
b.logical = 0xe010;
192+
b.size = 0x40;
193+
194+
munit_assert_int(section_overlap(&a, &b), ==, 1);
195+
196+
b.type = SECTION_TYPE_DATA;
197+
munit_assert_int(section_overlap(&a, &b), ==, -1);
198+
199+
a.type = SECTION_TYPE_DATA;
200+
a.logical = 0x0200;
201+
a.size = 0x10;
202+
203+
b.logical = 0x01e0;
204+
b.size = 0x50;
205+
206+
munit_assert_int(section_overlap(&a, &b), ==, 1);
207+
208+
b.page = 0x02;
209+
munit_assert_int(section_overlap(&a, &b), ==, 0);
210+
211+
b.page = a.page;
212+
b.size = 0x01;
213+
munit_assert_int(section_overlap(&a, &b), ==, 0);
214+
215+
return MUNIT_OK;
216+
}
217+
218+
219+
MunitResult section_add_test(const MunitParameter params[], void* fixture) {
220+
// [todo] add sections
221+
// [todo] add one that merge
222+
// [todo] add one with merge+error
223+
return MUNIT_OK;
224+
}
225+
178226
static MunitTest section_tests[] = {
179227
{ "/sort", section_sort_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
180228
{ "/load", section_load_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
229+
{ "/overlap", section_overlap_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
230+
{ "/add", section_add_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
181231
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
182232
};
183233

0 commit comments

Comments
 (0)