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