symbolic4
foundation.c
Go to the documentation of this file.
1 
2 /*
3 
4  Copyright (c) 2019 Hannes Eberhard
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 
24  */
25 
26 #include "symbolic4.h"
27 
31 
32 /**
33 
34  @brief Allocates and keeps track of memory
35 
36  @details
37  The pointer to the allocated memory is stored in the
38  @c allocated_pointers array.
39 
40  @pre
41  - The @c allocated_pointers array must be initialized with @c NULL,
42  or else the loop won't work.
43 
44  @warning
45  - If the memory allocation fails, @c set_handle_unrecoverable_error() is
46  called.
47 
48  @param[in] length The length/count of the elements.
49  @param[in] size The size of one element (see @c sizeof()).
50 
51  @return
52  - A void-pointer to the allocated memory.
53 
54  @see
55  - smart_free()
56  - smart_free_all()
57 
58  */
59 void* smart_alloc(uint8_t length, size_t size) {
60  uint16_t i;
61  void* pointer = calloc(length, size);
64  for (i = 0; allocated_pointers[i] != NULL && i < ALLOCATED_POINTERS_LENGTH - 1; i++);
65  allocated_pointers[i] = pointer;
66  }
67  return pointer;
68 }
69 
70 /**
71 
72  @brief Resizes a pointer
73 
74  @details
75  The resized pointer to the allocated memory is stored in the
76  @c allocated_pointers array.
77 
78  @param[in] source The pointer to be resized.
79  @param[in] length The new length/count of the elements.
80  @param[in] size The size of one element (see @c sizeof()).
81 
82  @see
83  - smart_alloc()
84 
85  */
86 void* smart_realloc(void* source, uint8_t length, size_t size) {
87  uint16_t i;
88  void* pointer = realloc(source, length * size);
90  if (pointer != source && smart_alloc_is_recording) {
91  for (i = 0; allocated_pointers[i] != NULL && i < ALLOCATED_POINTERS_LENGTH; i++);
92  allocated_pointers[i] = pointer;
93  }
94  return pointer;
95 }
96 
97 /**
98 
99  @brief Frees a pointer
100 
101  @details
102  This function frees a pointer and sets its corresponding entry in the
103  @c allocated_pointers array to @c NULL.
104 
105  @param[in] pointer The pointer to be freed.
106 
107  @see
108  - smart_alloc()
109  - smart_free_all()
110 
111  */
112 void smart_free(void* pointer) {
113  uint16_t i;
114  if (pointer == NULL) return;
115  for (i = 0; allocated_pointers[i] != pointer && i < ALLOCATED_POINTERS_LENGTH; i++);
116  free(pointer);
117  allocated_pointers[i] = NULL;
118 }
119 
120 /**
121 
122  @brief Frees all pointers
123 
124  @details
125  This function frees all pointers allocated with @c smart_alloc() by
126  iteratively calling @c smart_free().
127 
128  @see
129  - smart_alloc()
130  - smart_free()
131 
132  */
133 void smart_free_all(void) {
134  uint16_t i;
135  for (i = 0; i < ALLOCATED_POINTERS_LENGTH; i++) {
137  }
138 }
139 
140 /**
141 
142  @brief Sets @c current_error to the arguments provided
143 
144  @param[in] domain
145  @param[in] identifier
146  @param[in] body
147 
148  @return
149  - Returns always @c RETS_ERROR
150 
151  */
152 uint8_t set_error(error_domain domain, error_identifier identifier, const char* body) {
153  current_error.domain = domain;
154  current_error.identifier = identifier;
155  strcpy(current_error.body, body);
156  return RETS_ERROR;
157 }
158 
159 /**
160 
161  @brief Handles severe and unrecoverable errors
162 
163  @details
164  This function serves as the last resort when the program encounters
165  exceptionally severe errors, such as a failed memory allocation,
166  from which it can't recover itself.
167  The
168  @code
169  while (true);
170  @endcode
171  loop may be replaced with system-specific error handling.
172 
173  @warning
174  - This function should only be called if everything else has failed.
175 
176  @param[in] domain The error domain.
177  @param[in] identifier The error identifier.
178  @param[in] body The error body.
179 
180  */
181 void set_handle_unrecoverable_error(error_domain domain, error_identifier identifier, const char* body) {
182  current_error.domain = domain;
183  current_error.identifier = identifier;
184  strcpy(current_error.body, body);
185  while (true);
186 }
187 
188 double uintmax_max_value(void) {
189  return pow(2, sizeof(uintmax_t) * 8) - 1000;
190 }
191 
192 /**
193 
194  @brief Converts a string to lowercase
195 
196  @details
197  This function copies the source string and converts that copy
198  character-wise to lowercase. The resulting string must be freed.
199 
200  @param[in] string The string to convert.
201 
202  @return
203  - The new string in lowercase letters.
204 
205  */
206 char* string_to_lower(const char* string) {
207  uint8_t i;
208  char* result = smart_alloc(strlen(string) + 1, sizeof(char));
209  strcpy(result, string);
210  for (i = 0; result[i] != '\0'; i++) {
211  result[i] = tolower(result[i]);
212  }
213  return result;
214 }
215 
216 void itoa(char* buffer, uintmax_t source) {
217 
218  uintmax_t i = 1;
219  uint8_t buffer_position = 0;
220 
221  while (source >= 10 * i) {
222  i *= 10;
223  }
224 
225  do {
226  buffer[buffer_position++] = (((source - source % i) / i) % 10) + '0';
227  } while (i /= 10);
228 
229  buffer[buffer_position] = '\0';
230 
231 }
232 
233 void dtoa(char* buffer, uint8_t length, double source) {
234 
235  uint8_t buffer_position = 0;
236 
237  if (source < 0) {
238  buffer[buffer_position++] = '-';
239  source *= -1;
240  }
241 
242  itoa(buffer + buffer_position, source);
243  buffer_position = strlen(buffer);
244 
245  buffer[buffer_position++] = '.';
246 
247  for (buffer_position = strlen(buffer); buffer_position < length - 1 && source != 0; buffer_position++) {
248  source = (source - (uint8_t) source) * 10;
249  buffer[buffer_position] = (uint8_t) source + '0';
250  }
251 
252  buffer[length - 1] = '\0';
253 
254 }
smart_free_all
void smart_free_all(void)
Frees all pointers.
Definition: foundation.c:133
symbolic4.h
error::identifier
error_identifier identifier
Definition: foundation.h:74
smart_free
void smart_free(void *pointer)
Frees a pointer.
Definition: foundation.c:112
error
Definition: foundation.h:72
ERRI_MEMORY_ALLOCATION
Definition: foundation.h:51
dtoa
void dtoa(char *buffer, uint8_t length, double source)
Definition: foundation.c:233
uintmax_max_value
double uintmax_max_value(void)
Definition: foundation.c:188
itoa
void itoa(char *buffer, uintmax_t source)
Definition: foundation.c:216
RETS_ERROR
Definition: foundation.h:66
set_handle_unrecoverable_error
void set_handle_unrecoverable_error(error_domain domain, error_identifier identifier, const char *body)
Handles severe and unrecoverable errors.
Definition: foundation.c:181
string_to_lower
char * string_to_lower(const char *string)
Converts a string to lowercase.
Definition: foundation.c:206
error::domain
error_domain domain
Definition: foundation.h:73
set_error
uint8_t set_error(error_domain domain, error_identifier identifier, const char *body)
Sets current_error to the arguments provided.
Definition: foundation.c:152
error::body
char body[20]
Definition: foundation.h:75
ERRD_SYSTEM
Definition: foundation.h:35
error_identifier
error_identifier
Definition: foundation.h:49
smart_alloc_is_recording
bool smart_alloc_is_recording
Definition: foundation.c:30
ALLOCATED_POINTERS_LENGTH
#define ALLOCATED_POINTERS_LENGTH
Definition: symbolic4.h:30
smart_realloc
void * smart_realloc(void *source, uint8_t length, size_t size)
Resizes a pointer.
Definition: foundation.c:86
allocated_pointers
void ** allocated_pointers
Definition: foundation.c:29
current_error
error current_error
Definition: foundation.c:28
error_domain
error_domain
Definition: foundation.h:33
smart_alloc
void * smart_alloc(uint8_t length, size_t size)
Allocates and keeps track of memory.
Definition: foundation.c:59