Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file lib.Memory.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2016-2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef LIB_MEMORY_HPP_ | ||
7 | #define LIB_MEMORY_HPP_ | ||
8 | |||
9 | #include "lib.Types.hpp" | ||
10 | |||
11 | namespace eoos | ||
12 | { | ||
13 | namespace lib | ||
14 | { | ||
15 | |||
16 | /** | ||
17 | * @class Memory | ||
18 | * @brief Memory manipulator class. | ||
19 | */ | ||
20 | class Memory | ||
21 | { | ||
22 | |||
23 | public: | ||
24 | |||
25 | /** | ||
26 | * @brief Copies a block of memory. | ||
27 | * | ||
28 | * @param dst A destination array where the content would be copied. | ||
29 | * @param src A source array to be copied. | ||
30 | * @param len A number of bytes to copy. | ||
31 | * @return A pointer to the destination array, or NULLPTR if an error has been occurred. | ||
32 | */ | ||
33 | 5 | static void* memcpy(void* const dst, void const* const src, size_t len) | |
34 | { | ||
35 | 5 | void* res( NULLPTR ); | |
36 |
4/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
|
5 | if( (dst != NULLPTR) && (src != NULLPTR) ) |
37 | { | ||
38 | 2 | ucell_t const* sp( static_cast<ucell_t const*>(src) ); ///< SCA MISRA-C++:2008 Justified Rule 5-2-8 | |
39 | 2 | ucell_t* dp( static_cast<ucell_t*>(dst) ); ///< SCA MISRA-C++:2008 Justified Rule 5-2-8 | |
40 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | while(len-- != 0U) ///< SCA MISRA-C++:2008 Justified Rule 5-2-10 |
41 | { | ||
42 | 4 | *dp++ = *sp++; ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 and Rule 5-2-10 | |
43 | } | ||
44 | 2 | res = dst; | |
45 | } | ||
46 | 5 | return res; | |
47 | } | ||
48 | |||
49 | /** | ||
50 | * @brief Fills a block of memory. | ||
51 | * | ||
52 | * @param dst A destination block of memory would be filled. | ||
53 | * @param val A least significant byte of value to be set. | ||
54 | * @param len A number of bytes to be set to the value. | ||
55 | * @return A pointer to the destination memory, or NULLPTR if an error has been occurred. | ||
56 | */ | ||
57 | 27 | static void* memset(void* const dst, int32_t const val, size_t len) | |
58 | { | ||
59 | 27 | void* res( NULLPTR ); | |
60 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
|
27 | if(dst != NULLPTR) |
61 | { | ||
62 | 26 | ucell_t* dp( static_cast<ucell_t*>(dst) ); ///< SCA MISRA-C++:2008 Justified Rule 5-2-8 | |
63 | 26 | ucell_t const uc( static_cast<ucell_t>(val) ); | |
64 |
2/2✓ Branch 0 taken 28812 times.
✓ Branch 1 taken 26 times.
|
28838 | while(len-- != 0U) ///< SCA MISRA-C++:2008 Justified Rule 5-2-10 |
65 | { | ||
66 | 28812 | *dp++ = uc; ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 and Rule 5-2-10 | |
67 | } | ||
68 | 26 | res = dst; | |
69 | } | ||
70 | 27 | return res; | |
71 | } | ||
72 | |||
73 | /** | ||
74 | * @brief Returns the length of a passed string . | ||
75 | * | ||
76 | * @param str A character string would be measured. | ||
77 | * @return The length of the passed string, and zero if NULLPTR given. | ||
78 | */ | ||
79 | 3 | static size_t strlen(char_t const* str) | |
80 | { | ||
81 | 3 | size_t len( 0U ); | |
82 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if(str != NULLPTR) |
83 | { | ||
84 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
|
15 | while( *str != '\0' ) |
85 | { | ||
86 | 13 | len++; | |
87 | 13 | str++; ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
88 | } | ||
89 | } | ||
90 | 3 | return len; | |
91 | } | ||
92 | |||
93 | /** | ||
94 | * @brief Copies one string to another . | ||
95 | * | ||
96 | * @param dst A destination array where the content would be copied. | ||
97 | * @param src A character string to be copied. | ||
98 | * @return A pointer to the destination string, or NULLPTR if an error has been occurred. | ||
99 | */ | ||
100 | 111 | static char_t* strcpy(char_t* const dst, char_t const* src) | |
101 | { | ||
102 | 111 | char_t* res( NULLPTR ); | |
103 |
4/4✓ Branch 0 taken 109 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 1 times.
|
111 | if( (dst != NULLPTR) && (src != NULLPTR) ) |
104 | { | ||
105 | 108 | char_t* d( dst - 1 ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
106 | 108 | char_t const* s( src - 1 ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
107 |
2/2✓ Branch 0 taken 821 times.
✓ Branch 1 taken 108 times.
|
929 | while( (*++d = *++s) != '\0' ) {} ///< SCA MISRA-C++:2008 Justified Rule 5-0-15, Rule 5-2-10 and Rule 6-2-1 |
108 | 108 | res = dst; | |
109 | |||
110 | } | ||
111 | 111 | return res; | |
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * @brief Concatenates two strings. | ||
117 | * | ||
118 | * @param dst A destination character string where the content would be appended. | ||
119 | * @param src A character string to be appended. | ||
120 | * @return A pointer to the destination string, or NULLPTR if an error has been occurred. | ||
121 | */ | ||
122 | 4 | static char_t* strcat(char_t* const dst, char_t const* src) | |
123 | { | ||
124 | 4 | char_t* res( NULLPTR ); | |
125 |
4/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
4 | if( (dst != NULLPTR) && (src != NULLPTR) ) |
126 | { | ||
127 | 1 | char_t* d( dst - 1 ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
128 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 | while( *++d != '\0' ) {} ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 and Rule 5-2-10 |
129 | 1 | d--; ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
130 | 1 | char_t const* s( src - 1 ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 | |
131 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 | while( (*++d = *++s) != '\0' ) {} ///< SCA MISRA-C++:2008 Justified Rule 5-0-15, Rule 5-2-10 and Rule 6-2-1 |
132 | 1 | res = dst; | |
133 | } | ||
134 | 4 | return res; | |
135 | } | ||
136 | |||
137 | /** | ||
138 | * @brief Compares two strings. | ||
139 | * | ||
140 | * @param str1 Character string to be compared. | ||
141 | * @param str2 Character string to be compared. | ||
142 | * @return The value 0 if the string 1 is equal to the string 2; | ||
143 | * a value less than 0 if the first not match character of string 1 has lower value than in string 2; | ||
144 | * a value greater than 0 if the first not match character of string 1 has greater value than in string 2; | ||
145 | * or the minimum possible value if an error has been occurred. | ||
146 | */ | ||
147 | 8 | static int32_t strcmp(char_t const* str1, char_t const* str2) | |
148 | { | ||
149 | 8 | int32_t res( static_cast<int32_t>( 0x80000000U ) ); | |
150 |
4/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
|
8 | if( (str1 != NULLPTR) && (str2 != NULLPTR) ) |
151 | { | ||
152 | while(true) | ||
153 | { | ||
154 | 18 | int32_t ch1( static_cast<int32_t>(*str1++) ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 and Rule 5-2-10 | |
155 | 18 | int32_t ch2( static_cast<int32_t>(*str2++) ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-15 and Rule 5-2-10 | |
156 | 18 | res = ch1 - ch2; | |
157 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 3 times.
|
18 | if( (ch1 == 0) || (res != 0) ) |
158 | { | ||
159 | break; | ||
160 | } | ||
161 | 13 | } | |
162 | } | ||
163 | 8 | return res; | |
164 | } | ||
165 | |||
166 | /** | ||
167 | * @brief Converts an integer number to a string. | ||
168 | * | ||
169 | * The function converts an integer value into a character string using the base parameter, | ||
170 | * which has to be 2, 8, 10, or 16 based numerals for converting to an appropriate numeral system. | ||
171 | * | ||
172 | * @note See exceptions below: | ||
173 | * | ||
174 | * Exception 1: Minimum negative value can be `T_MIN + 1` or greater. | ||
175 | * | ||
176 | * Exception 2: Only if the base is decimal, a passed number is available to be negative value, | ||
177 | * and the resulting string of these values is preceded with a minus sign. | ||
178 | * | ||
179 | * Exception 3: A hexadecimal number includes lower case characters, and any resulting strings | ||
180 | * do not contain any suffixes or prefixes for identifying a numeral system. | ||
181 | * | ||
182 | * @todo Rework the implementation to avoid the exceptions. | ||
183 | * | ||
184 | * @param val A value that would be converted to a string. | ||
185 | * @param str A character string for a result of the conversion. | ||
186 | * @param base A numerical base used to represent a value as a string. | ||
187 | * @return True if the conversion has been completed successfully. | ||
188 | */ | ||
189 | template <typename T> | ||
190 | 208 | static bool_t itoa(T const val, char_t* str, Number::Base const base = Number::BASE_10) | |
191 | { | ||
192 | 208 | const int32_t LENGTH( ( static_cast<int32_t>( sizeof(T) ) * 8) + 1 ); | |
193 | 208 | bool_t res( false ); | |
194 |
1/2✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
|
208 | if(str != NULLPTR) |
195 | { | ||
196 | char_t temp[LENGTH]; | ||
197 | bool_t isNegative; | ||
198 | 208 | int32_t index( LENGTH - 1 ); | |
199 | 208 | res = true; | |
200 | 208 | temp[index--] = '\0'; ///< SCA MISRA-C++:2008 Justified Rule 5-0-11 and Rule 5-2-10 | |
201 | do | ||
202 | { | ||
203 | // Test for available base | ||
204 |
3/3✓ Branch 0 taken 56 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 8 times.
|
208 | switch(base) |
205 | { | ||
206 | 112 | case Number::BASE_2: | |
207 | case Number::BASE_8: | ||
208 | case Number::BASE_16: | ||
209 | { | ||
210 | 112 | isNegative = false; | |
211 | 112 | break; | |
212 | } | ||
213 | 80 | case Number::BASE_10: | |
214 | { | ||
215 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 28 times.
|
80 | isNegative = ( !isPositive(val) ) ? true : false; |
216 | 80 | break; | |
217 | } | ||
218 | 16 | default: | |
219 | { | ||
220 | 16 | res = false; | |
221 | 16 | break; | |
222 | } | ||
223 | } | ||
224 | // If the base is not available | ||
225 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 96 times.
|
208 | if(res == false) |
226 | { | ||
227 | 16 | break; | |
228 | } | ||
229 | // Prepare absolute value | ||
230 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 84 times.
|
192 | T module( isNegative ? (0 - val) : val ); |
231 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 80 times.
|
192 | if( !isPositive(module) ) |
232 | { | ||
233 | 32 | res = false; | |
234 | 32 | break; | |
235 | } | ||
236 | // Do the conversion | ||
237 | // @todo Revise possibility to declare index of size_t underlying type. | ||
238 | // But in the case index will always more than or equal zero. | ||
239 | // Thus, algorithm shall be re-worked. | ||
240 |
1/2✓ Branch 0 taken 781 times.
✗ Branch 1 not taken.
|
1562 | while(index >= 0) |
241 | { | ||
242 | char_t ch; | ||
243 | 1562 | T digit( module % static_cast<T>(base) ); | |
244 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 643 times.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 22 times.
|
1562 | if( (base == Number::BASE_16) && (digit > 9) ) |
245 | { | ||
246 | 232 | ch = 'a'; | |
247 | 232 | digit -= 10; | |
248 | } | ||
249 | else | ||
250 | { | ||
251 | 1330 | ch = '0'; | |
252 | } | ||
253 | 1562 | temp[index--] = static_cast<char_t>(digit + ch); ///< SCA MISRA-C++:2008 Justified Rule 3-9-2, Rule 5-0-11 and Rule 5-2-10 | |
254 | 1562 | module = module / static_cast<T>(base); | |
255 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 701 times.
|
1562 | if(module == 0) |
256 | { | ||
257 | 160 | break; | |
258 | } | ||
259 | } | ||
260 | // Add minus | ||
261 |
3/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
160 | if( isNegative && (index >= 0) ) |
262 | { | ||
263 | 16 | temp[index--] = '-'; ///< SCA MISRA-C++:2008 Justified Rule 5-0-11 and Rule 5-2-10 | |
264 | } | ||
265 | 160 | res = true; | |
266 | } | ||
267 | while(false); | ||
268 | // Copy the temp string to the destination string | ||
269 | // @todo Replace this with strncpy | ||
270 | 208 | strcpy(str, &temp[++index]); ///< SCA MISRA-C++:2008 Justified Rule 5-2-10 | |
271 | } | ||
272 | 208 | return res; | |
273 | } | ||
274 | |||
275 | /** | ||
276 | * @brief Converts a string to an integer number. | ||
277 | * | ||
278 | * @param str A character string that would be converted to a number. | ||
279 | * @param base A numerical base used to parse the string. | ||
280 | * @return The resulting number, 0 if an error is occurred. | ||
281 | */ | ||
282 | template <typename T> | ||
283 | 18 | static T atoi(char_t const* str, Number::Base const base = Number::BASE_10) | |
284 | { | ||
285 | 18 | bool_t isBase( false ); | |
286 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1 times.
|
18 | switch(base) |
287 | { | ||
288 | 17 | case Number::BASE_2: | |
289 | case Number::BASE_8: | ||
290 | case Number::BASE_10: | ||
291 | case Number::BASE_16: | ||
292 | { | ||
293 | 17 | isBase = true; | |
294 | 17 | break; | |
295 | } | ||
296 | 1 | default: | |
297 | { | ||
298 | 1 | isBase = false; | |
299 | 1 | break; | |
300 | } | ||
301 | } | ||
302 | 18 | T result( 0 ); | |
303 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1 times.
|
18 | if( isBase ) |
304 | { | ||
305 | 17 | T const multiplier( static_cast<T>(base) ); | |
306 | 17 | int32_t index( 0 ); | |
307 | 17 | bool_t isNegative( false ); | |
308 | // Look for whitespaces | ||
309 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 17 times.
|
23 | while( isSpace(str[index]) ) |
310 | { | ||
311 | 6 | index++; | |
312 | } | ||
313 | // Test a character if the number is negative for decimal base | ||
314 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
|
17 | if(base == Number::BASE_10) |
315 | { | ||
316 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
|
9 | if( str[index] == '-' ) |
317 | { | ||
318 | 2 | isNegative = true; | |
319 | 2 | index++; | |
320 | } | ||
321 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | else if( str[index] == '+' ) |
322 | { | ||
323 | 2 | isNegative = false; | |
324 | 2 | index++; | |
325 | } | ||
326 | else | ||
327 | { | ||
328 | 5 | isNegative = false; | |
329 | } | ||
330 | } | ||
331 | // Do fast calculation for no hexadecimal base | ||
332 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 4 times.
|
17 | if(base != Number::BASE_16) |
333 | { | ||
334 |
2/2✓ Branch 1 taken 141 times.
✓ Branch 2 taken 13 times.
|
154 | while( isDigit(str[index], base) ) |
335 | { | ||
336 | 141 | result *= multiplier; | |
337 | 141 | result += static_cast<T>( str[index++] - '0' ); ///< SCA MISRA-C++:2008 Justified Rule 5-2-10 | |
338 | } | ||
339 | } | ||
340 | else | ||
341 | { | ||
342 | char_t subtrahend; | ||
343 | int32_t addend; | ||
344 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 4 times.
|
36 | while( isDigit(str[index], base) ) |
345 | { | ||
346 | 32 | detectMathOperands(str[index], subtrahend, addend); | |
347 | 32 | result *= static_cast<T>( base ); | |
348 | 32 | result += static_cast<T>( str[index++] - subtrahend ); ///< SCA MISRA-C++:2008 Justified Rule 4-5-3, Rule 5-0-11 and Rule 5-2-10 | |
349 | 32 | result += static_cast<T>( addend ); | |
350 | } | ||
351 | } | ||
352 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 15 times.
|
17 | result = isNegative ? (0 - result) : result; |
353 | } | ||
354 | 18 | return result; | |
355 | } | ||
356 | |||
357 | private: | ||
358 | |||
359 | /** | ||
360 | * @brief Tests if a value is signed or unsigned. | ||
361 | * | ||
362 | * @param value A value that would be tested. | ||
363 | * @return True if the value has been negative. | ||
364 | * | ||
365 | * @note The `volatile` keyword added, as the GCC 7.5.0 compiler doesn't call this function optimizing it for Release build. | ||
366 | * This behavior is cause a bug in `itoa` function with -9223372036854775808 value of int64_t type trying to check module of the value. | ||
367 | * Partial specialization of the template function for int64_t also doesn't help. | ||
368 | */ | ||
369 | template <typename T> | ||
370 | 272 | static bool_t isPositive(volatile T value) | |
371 | { | ||
372 |
4/4✓ Branch 0 taken 44 times.
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 28 times.
|
272 | return ( (value > 0) || (value == 0) ) ? true : false; |
373 | } | ||
374 | |||
375 | /** | ||
376 | * @brief Tests if a character is a whitespace character. | ||
377 | * | ||
378 | * @param character A character code. | ||
379 | * @return True if the character is whitespace. | ||
380 | */ | ||
381 | 23 | static bool_t isSpace(char_t const character) | |
382 | { | ||
383 | 23 | bool_t result( true ); | |
384 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 17 times.
|
23 | switch(character) |
385 | { | ||
386 | 6 | case ' ': | |
387 | case '\t': | ||
388 | case '\n': | ||
389 | case '\v': | ||
390 | case '\f': | ||
391 | case '\r': | ||
392 | { | ||
393 | 6 | break; | |
394 | } | ||
395 | 17 | default: | |
396 | { | ||
397 | 17 | result = false; | |
398 | 17 | break; | |
399 | } | ||
400 | } | ||
401 | 23 | return result; | |
402 | } | ||
403 | |||
404 | /** | ||
405 | * @brief Tests if a character is a decimal number. | ||
406 | * | ||
407 | * @param character A character code. | ||
408 | * @param base A numerical base used to parse the character. | ||
409 | * @return True if the character is a decimal number. | ||
410 | */ | ||
411 | 190 | static bool_t isDigit(char_t const character, Number::Base const base = Number::BASE_10) | |
412 | { | ||
413 | 190 | bool_t res( false ); | |
414 | 190 | int32_t const ch( static_cast<int32_t>(character) ); | |
415 |
4/5✓ Branch 0 taken 62 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 68 times.
✗ Branch 4 not taken.
|
190 | switch(base) |
416 | { | ||
417 | 62 | case Number::BASE_2: | |
418 | { | ||
419 |
3/4✓ Branch 0 taken 60 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
|
62 | res = ( (ch >= 0x30) && (ch <= 0x31) ) ? true : false; |
420 | 62 | break; | |
421 | } | ||
422 | 24 | case Number::BASE_8: | |
423 | { | ||
424 |
3/4✓ Branch 0 taken 22 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
24 | res = ( (ch >= 0x30) && (ch <= 0x37) ) ? true : false; |
425 | 24 | break; | |
426 | } | ||
427 | 36 | case Number::BASE_16: | |
428 | { | ||
429 | 36 | res = ( | |
430 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
|
32 | ( (ch >= 0x30) && (ch <= 0x39) ) |
431 |
4/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 12 times.
|
28 | || ( (ch >= 0x41) && (ch <= 0x46) ) |
432 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | || ( (ch >= 0x61) && (ch <= 0x66) ) |
433 |
4/4✓ Branch 0 taken 32 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
|
84 | ) ? true : false; |
434 | 36 | break; | |
435 | } | ||
436 | 68 | case Number::BASE_10: | |
437 | { | ||
438 |
4/4✓ Branch 0 taken 60 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 1 times.
|
68 | res = ( (ch >= 0x30) && (ch <= 0x39) ) ? true : false; |
439 | 68 | break; | |
440 | } | ||
441 | } | ||
442 | 190 | return res; | |
443 | } | ||
444 | |||
445 | /** | ||
446 | * @brief Detects subtrahend and addend for hex numbers. | ||
447 | * | ||
448 | * @param ch A testing character code. | ||
449 | * @param subtrahend A resulting subtrahend. | ||
450 | * @param addend A resulting addend. | ||
451 | */ | ||
452 | 32 | static void detectMathOperands(char_t const character, char_t& subtrahend, int32_t& addend) | |
453 | { | ||
454 | 32 | int32_t const ch( static_cast<int32_t>(character) ); | |
455 | // Test for uppercase letter | ||
456 |
4/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 12 times.
|
32 | if( (ch >= 0x41) && (ch <= 0x46) ) |
457 | { | ||
458 | 12 | subtrahend = 'A'; | |
459 | 12 | addend = 10; | |
460 | } | ||
461 | // Test for lowercase letter | ||
462 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
20 | else if( (ch >= 0x61) && (ch <= 0x66) ) |
463 | { | ||
464 | 12 | subtrahend = 'a'; | |
465 | 12 | addend = 10; | |
466 | } | ||
467 | else | ||
468 | { | ||
469 | 8 | subtrahend = '0'; | |
470 | 8 | addend = 0; | |
471 | } | ||
472 | 32 | } | |
473 | |||
474 | }; | ||
475 | |||
476 | } // namespace lib | ||
477 | } // namespace eoos | ||
478 | #endif // LIB_MEMORY_HPP_ | ||
479 |