@@ -20,28 +20,39 @@ sum_lines(spiral_t spiral, size_t start, size_t end) {
2020}
2121
2222/*
23- * given a spiral_t struct, a pair of co-ords specifying the start point and
24- * indexes of the lowest and highest line segments to use, return a
25- * co_ord_array_t struct containing all the co-ordinates of the line segments of
26- * the struct according to the current directions and lengths of the lines in
27- * the spiral.
23+ * given a spiral_t struct, a pointer to a co_ord_array_t, a pair of co-ords
24+ * specifying the start point and indexes of the lowest and highest line
25+ * segments to use, write to the co_ord_array_t struct all the co-ordinates of
26+ * the line segments of the struct according to the current directions and
27+ * lengths of the lines in the spiral.
2828 * each line segment is only one unit long, meaning multiple ones are needed for
2929 * lines longer than one unit.
30+ * returns a status struct with error information (if any)
3031 */
31- co_ord_array_t
32- spiral_points (spiral_t spiral , co_ord_t start_point , size_t start , size_t end ) {
32+ status_t
33+ spiral_points (
34+ spiral_t spiral , co_ord_array_t * output , co_ord_t start_point ,
35+ size_t start , size_t end
36+ ) {
37+ // prepare result status
38+ status_t result = {};
3339 // the amount of space needed is the sum of all line lengths + 1 for end
3440 size_t size = sum_lines (spiral , start , end ) + 1 ;
3541 // allocate memory
36- co_ord_array_t results = {
37- .items = calloc (sizeof (co_ord_t ), size ),
38- .size = size ,
39- };
42+ output -> items = calloc (sizeof (co_ord_t ), size );
43+ // catch malloc error
44+ if (output -> items == NULL ) {
45+ // set error information then early return
46+ result .location = DEBUG ;
47+ result .diagnostic = MALLOC_REFUSED ;
48+ return result ;
49+ }
50+ output -> size = size ;
4051 // start current co-ordinate at the given start point
4152 co_ord_t current = start_point ;
4253 // initialise independent result index
4354 size_t result_index = 0 ;
44- results . items [result_index ] = current ;
55+ output -> items [result_index ] = current ;
4556 // calculate all the specified co-ords
4657 for (size_t i = start ; i < end ; i ++ ) {
4758 // get current direction
@@ -50,11 +61,13 @@ spiral_points(spiral_t spiral, co_ord_t start_point, size_t start, size_t end) {
5061 for (length_t j = 0 ; j < spiral .lines [i ].length ; j ++ ) {
5162 current .x += direction .x ;
5263 current .y += direction .y ;
53- results . items [result_index + 1 ] = current ;
64+ output -> items [result_index + 1 ] = current ;
5465 result_index ++ ;
5566 }
5667 }
57- return results ;
68+ // all good
69+ result .diagnostic = OPERATION_OK ;
70+ return result ;
5871}
5972
6073/*
@@ -64,9 +77,12 @@ spiral_points(spiral_t spiral, co_ord_t start_point, size_t start, size_t end) {
6477 * each line segment is only one unit long, meaning multiple ones are needed for
6578 * lines longer than one unit. The co-ords are stored in the spiral's co_ord_cache
6679 * member and are re-used if they are still valid
80+ * returns a status struct with error information (if any)
6781 */
68- void
82+ status_t
6983cache_spiral_points (spiral_t * spiral , size_t limit ) {
84+ // prepare result status
85+ status_t result = {};
7086 // the amount of space needed is the sum of all line lengths + 1 for end
7187 size_t size = sum_lines (* spiral , 0 , limit ) + 1 ;
7288 // allocate / reallocate memory
@@ -82,6 +98,13 @@ cache_spiral_points(spiral_t * spiral, size_t limit) {
8298 spiral -> co_ord_cache .co_ords .items , sizeof (co_ord_t ) * size
8399 );
84100 }
101+ // catch malloc failure
102+ if (spiral -> co_ord_cache .co_ords .items == NULL ) {
103+ // set error information then early return
104+ result .location = DEBUG ;
105+ result .diagnostic = MALLOC_REFUSED ;
106+ return result ;
107+ }
85108 spiral -> co_ord_cache .co_ords .size = size ;
86109 // start at (0, 0) as origin
87110 co_ord_t current = { 0 , 0 , };
@@ -103,7 +126,14 @@ cache_spiral_points(spiral_t * spiral, size_t limit) {
103126 spiral -> co_ord_cache .co_ords .items [0 ] = current ;
104127 }
105128 // calculate the missing co-ords
106- co_ord_array_t missing = spiral_points (* spiral , current , smallest , limit );
129+ co_ord_array_t missing = {};
130+ status_t calculate_result = spiral_points (
131+ * spiral , & missing , current , smallest , limit
132+ );
133+ // return errors from previous call if needed
134+ if (calculate_result .diagnostic != OPERATION_OK ) {
135+ return calculate_result ;
136+ }
107137 // add the missing co-ords to the cache
108138 for (size_t i = result_index ; i < size ; i ++ ) {
109139 spiral -> co_ord_cache .co_ords .items [i ] = missing .items [i - result_index ];
@@ -116,6 +146,9 @@ cache_spiral_points(spiral_t * spiral, size_t limit) {
116146 spiral -> co_ord_cache .validity = (
117147 limit > spiral -> co_ord_cache .validity
118148 ) ? limit : spiral -> co_ord_cache .validity ;
149+ // return ok
150+ result .diagnostic = OPERATION_OK ;
151+ return result ;
119152}
120153
121154#ifdef __cplusplus
0 commit comments