1 /*
2 Copyright (C) 2014-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: dk3maidd.ctr
12 */
13
14 /** @file dk3maidd.c The dk3maidd module.
15 */
16
17
18 #include <libdk3c/dk3ma.h>
19
20
21
22
23
24
25 #if DK3_CHAR_SIZE > 1
26 /** Constant numeric values.
27 */
28 static dk3_um_t const dk3maidd_um_array[] = {
29 #if DK3_HAVE_LONG_LONG
30 /* 0 */ (dk3_um_t)10ULL,
31 /* 1 */ (dk3_um_t)1ULL,
32 /* 2 */ (dk3_um_t)2ULL,
33 /* 3 */ (dk3_um_t)3ULL,
34 /* 4 */ (dk3_um_t)4ULL,
35 /* 5 */ (dk3_um_t)5ULL,
36 /* 6 */ (dk3_um_t)6ULL,
37 /* 7 */ (dk3_um_t)7ULL,
38 /* 8 */ (dk3_um_t)8ULL,
39 /* 9 */ (dk3_um_t)9ULL,
40 /* 10 */ (dk3_um_t)10ULL,
41 /* 11 */ (dk3_um_t)11ULL,
42 /* 12 */ (dk3_um_t)12ULL,
43 /* 13 */ (dk3_um_t)13ULL,
44 /* 14 */ (dk3_um_t)14ULL,
45 /* 15 */ (dk3_um_t)15ULL,
46 /* 16 */ (dk3_um_t)16ULL
47 #else
48 /* 0 */ (dk3_um_t)10UL,
49 /* 1 */ (dk3_um_t)1UL,
50 /* 2 */ (dk3_um_t)2UL,
51 /* 3 */ (dk3_um_t)3UL,
52 /* 4 */ (dk3_um_t)4UL,
53 /* 5 */ (dk3_um_t)5UL,
54 /* 6 */ (dk3_um_t)6UL,
55 /* 7 */ (dk3_um_t)7UL,
56 /* 8 */ (dk3_um_t)8UL,
57 /* 9 */ (dk3_um_t)9UL,
58 /* 10 */ (dk3_um_t)10UL,
59 /* 11 */ (dk3_um_t)11UL,
60 /* 12 */ (dk3_um_t)12UL,
61 /* 13 */ (dk3_um_t)13UL,
62 /* 14 */ (dk3_um_t)14UL,
63 /* 15 */ (dk3_um_t)15UL,
64 /* 16 */ (dk3_um_t)16UL
65 #endif
66 /* if DK3_HAVE_LONG_LONG */
67 };
68 #endif
69 /* if DK3_CHAR_SIZE > 1 */
70
71
72 #if DK3_CHAR_SIZE > 1
73 /** Find start of text in string.
74 @param str String to search for text.
75 @return Pointer to start of text on success, NULL on error.
76 */
77 static
78 dkChar const *
dk3maidd_str_start(dkChar const * str)79 dk3maidd_str_start(dkChar const *str)
80 {
81 dkChar const *back = NULL;
82 if (NULL != str) {
83 back = str;
84 while((dkT(' ') == *back) || (dkT('\t') == *back)) { back++; }
85 switch(*back) {
86 case dkT('\0'): case dkT('\n'): case dkT('\r'): {
87 back = NULL;
88 } break;
89 }
90 }
91 return back;
92 }
93 #endif
94
95
96
97 int
dk3ma_um_from_string(dk3_um_t * rp,dkChar const * src,int * ec)98 dk3ma_um_from_string(dk3_um_t *rp, dkChar const *src, int *ec)
99 {
100 #if DK3_CHAR_SIZE > 1
101 dkChar const *ptr = NULL; /* Current char to process */
102 dk3_um_t val = DK3_UM_0; /* Value found */
103 dk3_um_t op = DK3_UM_0; /* Operand to add */
104 int mec = 0; /* Math error code */
105 int back = 0; /* Function result */
106 int found = 0; /* Flag: Digits found */
107 int cc = 1; /* Flag: Can continue */
108 int action = 0; /* Action to take */
109
110 if ((NULL != rp) && (NULL != src)) {
111 ptr = dk3maidd_str_start(src);
112 if (NULL != ptr) {
113 while (0 != cc) {
114 action = 0;
115 switch(*(ptr++)) {
116 case dkT('\0'): { /* End of string */
117 cc = 0;
118 if (0 != found) {
119 back = 1;
120 } else {
121 if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
122 }
123 } break;
124 case dkT('0'): {
125 found = 1; action = 1; op = DK3_UM_0;
126 } break;
127 case dkT('1'): {
128 found = 1; action = 1; op = dk3maidd_um_array[1];
129 } break;
130 case dkT('2'): {
131 found = 1; action = 1; op = dk3maidd_um_array[2];
132 } break;
133 case dkT('3'): {
134 found = 1; action = 1; op = dk3maidd_um_array[3];
135 } break;
136 case dkT('4'): {
137 found = 1; action = 1; op = dk3maidd_um_array[4];
138 } break;
139 case dkT('5'): {
140 found = 1; action = 1; op = dk3maidd_um_array[5];
141 } break;
142 case dkT('6'): {
143 found = 1; action = 1; op = dk3maidd_um_array[6];
144 } break;
145 case dkT('7'): {
146 found = 1; action = 1; op = dk3maidd_um_array[7];
147 } break;
148 case dkT('8'): {
149 found = 1; action = 1; op = dk3maidd_um_array[8];
150 } break;
151 case dkT('9'): {
152 found = 1; action = 1; op = dk3maidd_um_array[9];
153 } break;
154 default: { /* Non-digit */
155 cc = 0;
156 if (0 != found) {
157 back = 1;
158 }
159 if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
160 } break;
161 }
162 if (0 != cc) {
163 switch(action) {
164 case 1: {
165 val = dk3ma_um_add_ok(
166 dk3ma_um_mul_ok(val, dk3maidd_um_array[0], &mec), op, &mec
167 );
168 if (0 != mec) {
169 cc = 0;
170 val = DK3_UM_MAX;
171 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
172 }
173 } break;
174 }
175 }
176 }
177 } else {
178 if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
179 }
180 *rp = val;
181 #if DK3_ON_WINDOWS
182
183 #else
184 #if DK3_HAVE_INTMAX_T
185
186 #else
187 #if DK3_HAVE_LONG_LONG
188
189 #else
190
191 #endif
192 #endif
193 #endif
194 } else {
195 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
196 }
197 return back;
198 #else
199 return (dk3ma_um_from_c8_string(rp, src, ec));
200 #endif
201 }
202
203
204
205 int
dk3ma_im_from_string(dk3_im_t * rp,dkChar const * src,int * ec)206 dk3ma_im_from_string(dk3_im_t *rp, dkChar const *src, int *ec)
207 {
208 #if DK3_CHAR_SIZE > 1
209 dkChar const *ptr = NULL; /* Start of text */
210 dk3_um_t umv = DK3_UM_0; /* Temporary value */
211 dk3_im_t val = DK3_IM_0; /* Conversion result */
212 int back = 0; /* Function result */
213 if ((NULL != rp) && (NULL != src)) {
214 ptr = dk3maidd_str_start(src);
215 if (NULL != ptr) {
216 if (dkT('-') == *ptr) {
217 ptr++;
218 if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
219 if ((dk3_um_t)DK3_IM_MAX >= umv) {
220 val = (dk3_im_t)umv;
221 val = DK3_IM_0 - val;
222 back = 1;
223 } else {
224 val = DK3_IM_MIN;
225 #if VERSION_BEFORE_20140924
226 if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
227 #else
228 /* 2014-09-24: Fixed warning about integer overflow in constant.
229 */
230 if (((dk3_um_t)(DK3_IM_MAX) + (dk3_um_t)1UL) == umv)
231 #endif
232 {
233 back = 1;
234 } else {
235 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
236 }
237 }
238 } else {
239 val = (dk3_im_t)umv;
240 }
241 } else {
242 if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
243 if ((dk3_um_t)DK3_IM_MAX >= umv) {
244 val = (dk3_im_t)umv;
245 back = 1;
246 } else {
247 val = DK3_IM_MAX;
248 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
249 }
250 } else {
251 val = (dk3_im_t)umv;
252 }
253 }
254 } else {
255 if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
256 }
257 *rp = val;
258 } else {
259 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
260 }
261 return back;
262 #else
263 return (dk3ma_im_from_c8_string(rp, src, ec));
264 #endif
265 }
266
267
268
269 int
dk3ma_us_from_string(unsigned short * rp,dkChar const * src,int * ec)270 dk3ma_us_from_string(unsigned short *rp, dkChar const *src, int *ec)
271 {
272 #if DK3_CHAR_SIZE > 1
273 dk3_um_t val = DK3_UM_0;
274 int back = 0;
275 if ((NULL != rp) && (NULL != src)) {
276 if (0 != dk3ma_um_from_string(&val, src, ec)) {
277 if ((dk3_um_t)DK3_US_MAX >= val) {
278 *rp = (unsigned short)val;
279 back = 1;
280 } else {
281 *rp = DK3_US_MAX;
282 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
283 }
284 } else {
285 *rp = (unsigned short)val;
286 }
287 } else {
288 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
289 }
290 return back;
291 #else
292 return (dk3ma_us_from_c8_string(rp, src, ec));
293 #endif
294 }
295
296
297
298 int
dk3ma_s_from_string(short * rp,dkChar const * src,int * ec)299 dk3ma_s_from_string(short *rp, dkChar const *src, int *ec)
300 {
301 #if DK3_CHAR_SIZE > 1
302 dk3_im_t val = DK3_IM_0;
303 int back = 0;
304 if ((NULL != rp) && (NULL != src)) {
305 if (0 != dk3ma_im_from_string(&val, src, ec)) {
306 if (((dk3_im_t)DK3_S_MIN <= val) && ((dk3_im_t)DK3_S_MAX >= val)) {
307 *rp = (short)val;
308 back = 1;
309 } else {
310 if (DK3_IM_0 > val) { *rp = DK3_S_MIN; } else { *rp = DK3_S_MAX; }
311 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
312 }
313 } else {
314 *rp = (short)val;
315 }
316 } else {
317 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
318 }
319 return back;
320 #else
321 return (dk3ma_s_from_c8_string(rp, src, ec));
322 #endif
323 }
324
325
326
327 int
dk3ma_ui_from_string(unsigned * rp,dkChar const * src,int * ec)328 dk3ma_ui_from_string(unsigned *rp, dkChar const *src, int *ec)
329 {
330 #if DK3_CHAR_SIZE > 1
331 dk3_um_t val = DK3_UM_0;
332 int back = 0;
333 if ((NULL != rp) && (NULL != src)) {
334 if (0 != dk3ma_um_from_string(&val, src, ec)) {
335 if ((dk3_um_t)DK3_U_MAX >= val) {
336 *rp = (unsigned)val;
337 back = 1;
338 } else {
339 *rp = DK3_U_MAX;
340 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
341 }
342 } else {
343 *rp = (unsigned)val;
344 }
345 } else {
346 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
347 }
348 return back;
349 #else
350 return (dk3ma_ui_from_c8_string(rp, src, ec));
351 #endif
352 }
353
354
355
356 int
dk3ma_i_from_string(int * rp,dkChar const * src,int * ec)357 dk3ma_i_from_string(int *rp, dkChar const *src, int *ec)
358 {
359 #if DK3_CHAR_SIZE > 1
360 dk3_im_t val = DK3_IM_0;
361 int back = 0;
362 if ((NULL != rp) && (NULL != src)) {
363 if (0 != dk3ma_im_from_string(&val, src, ec)) {
364 if (((dk3_im_t)DK3_I_MIN <= val) && ((dk3_im_t)DK3_I_MAX >= val)) {
365 *rp = (int)val;
366 back = 1;
367 } else {
368 if (DK3_IM_0 > val) { *rp = DK3_I_MIN; } else { *rp = DK3_I_MAX; }
369 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
370 }
371 } else {
372 *rp = (int)val;
373 }
374 } else {
375 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
376 }
377 return back;
378 #else
379 return (dk3ma_i_from_c8_string(rp, src, ec));
380 #endif
381 }
382
383
384
385 int
dk3ma_ul_from_string(unsigned long * rp,dkChar const * src,int * ec)386 dk3ma_ul_from_string(unsigned long *rp, dkChar const *src, int *ec)
387 {
388 #if DK3_CHAR_SIZE > 1
389 dk3_um_t val = DK3_UM_0;
390 int back = 0;
391 if ((NULL != rp) && (NULL != src)) {
392 if (0 != dk3ma_um_from_string(&val, src, ec)) {
393 if ((dk3_um_t)DK3_UL_MAX >= val) {
394 *rp = (unsigned long)val;
395 back = 1;
396 } else {
397 *rp = DK3_UL_MAX;
398 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
399 }
400 } else {
401 *rp = (unsigned long)val;
402 }
403 } else {
404 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
405 }
406 return back;
407 #else
408 return (dk3ma_ul_from_c8_string(rp, src, ec));
409 #endif
410 }
411
412
413
414 int
dk3ma_l_from_string(long * rp,dkChar const * src,int * ec)415 dk3ma_l_from_string(long *rp, dkChar const *src, int *ec)
416 {
417 #if DK3_CHAR_SIZE > 1
418 dk3_im_t val = DK3_IM_0;
419 int back = 0;
420 if ((NULL != rp) && (NULL != src)) {
421 if (0 != dk3ma_im_from_string(&val, src, ec)) {
422 if (((dk3_im_t)DK3_L_MIN <= val) && ((dk3_im_t)DK3_L_MAX >= val)) {
423 *rp = (long)val;
424 back = 1;
425 } else {
426 if (DK3_IM_0 > val) { *rp = DK3_L_MIN; } else { *rp = DK3_L_MAX; }
427 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
428 }
429 } else {
430 *rp = (long)val;
431 }
432 } else {
433 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
434 }
435 return back;
436 #else
437 return (dk3ma_l_from_c8_string(rp, src, ec));
438 #endif
439 }
440
441
442 #if DK3_HAVE_LONG_LONG
443
444 int
dk3ma_ull_from_string(unsigned long long * rp,dkChar const * src,int * ec)445 dk3ma_ull_from_string(unsigned long long *rp, dkChar const *src, int *ec)
446 {
447 #if DK3_CHAR_SIZE > 1
448 dk3_um_t val = DK3_UM_0;
449 int back = 0;
450 if ((NULL != rp) && (NULL != src)) {
451 if (0 != dk3ma_um_from_string(&val, src, ec)) {
452 if ((dk3_um_t)DK3_ULL_MAX >= val) {
453 *rp = (unsigned long long)val;
454 back = 1;
455 } else {
456 *rp = DK3_ULL_MAX;
457 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
458 }
459 } else {
460 *rp = (unsigned long long)val;
461 }
462 } else {
463 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
464 }
465 return back;
466 #else
467 return (dk3ma_ull_from_c8_string(rp, src, ec));
468 #endif
469 }
470
471
472
473 int
dk3ma_ll_from_string(long long * rp,dkChar const * src,int * ec)474 dk3ma_ll_from_string(long long *rp, dkChar const *src, int *ec)
475 {
476 #if DK3_CHAR_SIZE > 1
477 dk3_im_t val = DK3_IM_0;
478 int back = 0;
479 if ((NULL != rp) && (NULL != src)) {
480 if (0 != dk3ma_im_from_string(&val, src, ec)) {
481 if (((dk3_im_t)DK3_LL_MIN <= val) && ((dk3_im_t)DK3_LL_MAX >= val)) {
482 *rp = (long long)val;
483 back = 1;
484 } else {
485 if (DK3_IM_0 > val) { *rp = DK3_LL_MIN; } else { *rp = DK3_LL_MAX; }
486 if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
487 }
488 } else {
489 *rp = (long long)val;
490 }
491 } else {
492 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
493 }
494 return back;
495 #else
496 return (dk3ma_ll_from_c8_string(rp, src, ec));
497 #endif
498 }
499
500 #endif
501
502 #if DK3_HAVE_INTMAX_T
503
504 int
dk3ma_uintmax_t_from_string(uintmax_t * rp,dkChar const * src,int * ec)505 dk3ma_uintmax_t_from_string(uintmax_t *rp, dkChar const *src, int *ec)
506 {
507 #if DK3_CHAR_SIZE > 1
508 dk3_um_t val = DK3_UM_0;
509 int back = 0;
510 if ((NULL != rp) && (NULL != src)) {
511 if (0 != dk3ma_um_from_string(&val, src, ec)) {
512 *rp = (uintmax_t)val;
513 back = 1;
514 } else {
515 *rp = (uintmax_t)val;
516 }
517 } else {
518 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
519 }
520 return back;
521 #else
522 return (dk3ma_uintmax_t_from_c8_string(rp, src, ec));
523 #endif
524 }
525
526
527
528 int
dk3ma_intmax_t_from_string(intmax_t * rp,dkChar const * src,int * ec)529 dk3ma_intmax_t_from_string(intmax_t *rp, dkChar const *src, int *ec)
530 {
531 #if DK3_CHAR_SIZE > 1
532 dk3_im_t val = DK3_IM_0;
533 int back = 0;
534 if ((NULL != rp) && (NULL != src)) {
535 if (0 != dk3ma_im_from_string(&val, src, ec)) {
536 *rp = (intmax_t)val;
537 back = 1;
538 } else {
539 *rp = (intmax_t)val;
540 }
541 } else {
542 if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
543 }
544 return back;
545 #else
546 return (dk3ma_intmax_t_from_c8_string(rp, src, ec));
547 #endif
548 }
549
550 #endif
551