fsl_str.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017, 2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 #include <math.h>
10 #include <stdarg.h>
11 #include <stdlib.h>
12 #include "fsl_str.h"
13 #include "fsl_debug_console_conf.h"
14 
15 /*******************************************************************************
16  * Definitions
17  ******************************************************************************/
18 
20 #ifndef HUGE_VAL
21 #define HUGE_VAL (99.e99)
22 #endif /* HUGE_VAL */
23 
24 #ifndef MAX_FIELD_WIDTH
25 #define MAX_FIELD_WIDTH 99U
26 #endif
27 
28 #if PRINTF_ADVANCED_ENABLE
29 
30 enum _debugconsole_printf_flag
31 {
32  kPRINTF_Minus = 0x01U,
33  kPRINTF_Plus = 0x02U,
34  kPRINTF_Space = 0x04U,
35  kPRINTF_Zero = 0x08U,
36  kPRINTF_Pound = 0x10U,
37  kPRINTF_LengthChar = 0x20U,
38  kPRINTF_LengthShortInt = 0x40U,
39  kPRINTF_LengthLongInt = 0x80U,
40  kPRINTF_LengthLongLongInt = 0x100U,
41 };
42 #endif /* PRINTF_ADVANCED_ENABLE */
43 
46 {
47  kSCANF_Suppress = 0x2U,
48  kSCANF_DestMask = 0x7cU,
49  kSCANF_DestChar = 0x4U,
51  kSCANF_DestSet = 0x10U,
52  kSCANF_DestInt = 0x20U,
53  kSCANF_DestFloat = 0x30U,
54  kSCANF_LengthMask = 0x1f00U,
55 #if SCANF_ADVANCED_ENABLE
56  kSCANF_LengthChar = 0x100U,
57  kSCANF_LengthShortInt = 0x200U,
58  kSCANF_LengthLongInt = 0x400U,
59  kSCANF_LengthLongLongInt = 0x800U,
60 #endif /* SCANF_ADVANCED_ENABLE */
61 #if SCANF_FLOAT_ENABLE
62  kSCANF_LengthLongLongDouble = 0x1000U,
63 #endif /*PRINTF_FLOAT_ENABLE */
64  kSCANF_TypeSinged = 0x2000U,
65 };
66 
68 #if defined(__CC_ARM)
69 #pragma diag_suppress 1256
70 #endif /* __CC_ARM */
71 
72 /*******************************************************************************
73  * Prototypes
74  ******************************************************************************/
81 static uint32_t ScanIgnoreWhiteSpace(const char **s);
82 
94 static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps);
95 
96 #if PRINTF_FLOAT_ENABLE
97 
107 static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width);
108 
112 double modf(double input_dbl, double *intpart_ptr);
113 #endif /* PRINTF_FLOAT_ENABLE */
114 
115 /*************Code for process formatted data*******************************/
116 #if PRINTF_ADVANCED_ENABLE
117 static uint8_t PrintGetSignChar(int32_t ival, uint32_t flags_used, char *schar)
118 {
119  uint8_t len = 1U;
120  if (ival < 0)
121  {
122  *schar = '-';
123  }
124  else
125  {
126  if (0U != (flags_used & (uint32_t)kPRINTF_Plus))
127  {
128  *schar = '+';
129  }
130  else if (0U != (flags_used & (uint32_t)kPRINTF_Space))
131  {
132  *schar = ' ';
133  }
134  else
135  {
136  *schar = 0;
137  len = 0U;
138  }
139  }
140  return len;
141 }
142 #endif
143 
144 static uint32_t PrintGetWidth(const char **p, va_list *ap)
145 {
146  uint32_t field_width = 0;
147  uint8_t done = 0U;
148  char c;
149 
150  while (0U == done)
151  {
152  c = *(++(*p));
153  if ((c >= '0') && (c <= '9'))
154  {
155  (field_width) = ((field_width)*10U) + ((uint32_t)c - (uint32_t)'0');
156  }
157 #if PRINTF_ADVANCED_ENABLE
158  else if (c == '*')
159  {
160  (field_width) = (uint32_t)va_arg(*ap, uint32_t);
161  }
162 #endif /* PRINTF_ADVANCED_ENABLE */
163  else
164  {
165  /* We've gone one char too far. */
166  --(*p);
167  done = 1U;
168  }
169  }
170  return field_width;
171 }
172 
173 static uint32_t PrintGetPrecision(const char **s, va_list *ap, bool *valid_precision_width)
174 {
175  const char *p = *s;
176  uint32_t precision_width = 6U;
177  uint8_t done = 0U;
178 
179 #if PRINTF_ADVANCED_ENABLE
180  if (NULL != valid_precision_width)
181  {
182  *valid_precision_width = false;
183  }
184 #endif /* PRINTF_ADVANCED_ENABLE */
185  if (*++p == '.')
186  {
187  /* Must get precision field width, if present. */
188  precision_width = 0U;
189  done = 0U;
190  while (0U == done)
191  {
192  char c = *++p;
193  if ((c >= '0') && (c <= '9'))
194  {
195  precision_width = (precision_width * 10U) + ((uint32_t)c - (uint32_t)'0');
196 #if PRINTF_ADVANCED_ENABLE
197  if (NULL != valid_precision_width)
198  {
199  *valid_precision_width = true;
200  }
201 #endif /* PRINTF_ADVANCED_ENABLE */
202  }
203 #if PRINTF_ADVANCED_ENABLE
204  else if (c == '*')
205  {
206  precision_width = (uint32_t)va_arg(*ap, uint32_t);
207  if (NULL != valid_precision_width)
208  {
209  *valid_precision_width = true;
210  }
211  }
212 #endif /* PRINTF_ADVANCED_ENABLE */
213  else
214  {
215  /* We've gone one char too far. */
216  --p;
217  done = 1U;
218  }
219  }
220  }
221  else
222  {
223  /* We've gone one char too far. */
224  --p;
225  }
226  *s = p;
227  return precision_width;
228 }
229 
230 static uint32_t PrintIsobpu(const char c)
231 {
232  uint32_t ret = 0U;
233  if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
234  {
235  ret = 1U;
236  }
237  return ret;
238 }
239 
240 static uint32_t PrintIsdi(const char c)
241 {
242  uint32_t ret = 0U;
243  if ((c == 'd') || (c == 'i'))
244  {
245  ret = 1U;
246  }
247  return ret;
248 }
249 
250 static void PrintOutputdifFobpu(uint32_t flags_used,
251  uint32_t field_width,
252  uint32_t vlen,
253  char schar,
254  char *vstrp,
255  printfCb cb,
256  char *buf,
257  int32_t *count)
258 {
259 #if PRINTF_ADVANCED_ENABLE
260  /* Do the ZERO pad. */
261  if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
262  {
263  if ('\0' != schar)
264  {
265  cb(buf, count, schar, 1);
266  schar = '\0';
267  }
268  cb(buf, count, '0', (int)field_width - (int)vlen);
269  vlen = field_width;
270  }
271  else
272  {
273  if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
274  {
275  cb(buf, count, ' ', (int)field_width - (int)vlen);
276  if ('\0' != schar)
277  {
278  cb(buf, count, schar, 1);
279  schar = '\0';
280  }
281  }
282  }
283  /* The string was built in reverse order, now display in correct order. */
284  if ('\0' != schar)
285  {
286  cb(buf, count, schar, 1);
287  }
288 #else
289  cb(buf, count, ' ', (int)field_width - (int)vlen);
290 #endif /* PRINTF_ADVANCED_ENABLE */
291  while ('\0' != (*vstrp))
292  {
293  cb(buf, count, *vstrp--, 1);
294  }
295 #if PRINTF_ADVANCED_ENABLE
296  if (0U != (flags_used & (uint32_t)kPRINTF_Minus))
297  {
298  cb(buf, count, ' ', (int)field_width - (int)vlen);
299  }
300 #endif /* PRINTF_ADVANCED_ENABLE */
301 }
302 
303 static void PrintOutputxX(uint32_t flags_used,
304  uint32_t field_width,
305  uint32_t vlen,
306  bool use_caps,
307  char *vstrp,
308  printfCb cb,
309  char *buf,
310  int32_t *count)
311 {
312 #if PRINTF_ADVANCED_ENABLE
313  uint8_t dschar = 0;
314  if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
315  {
316  if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
317  {
318  cb(buf, count, '0', 1);
319  cb(buf, count, (use_caps ? 'X' : 'x'), 1);
320  dschar = 1U;
321  }
322  cb(buf, count, '0', (int)field_width - (int)vlen);
323  vlen = field_width;
324  }
325  else
326  {
327  if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
328  {
329  if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
330  {
331  vlen += 2U;
332  }
333  cb(buf, count, ' ', (int)field_width - (int)vlen);
334  if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
335  {
336  cb(buf, count, '0', 1);
337  cb(buf, count, (use_caps ? 'X' : 'x'), 1);
338  dschar = 1U;
339  }
340  }
341  }
342 
343  if ((0U != (flags_used & (uint32_t)kPRINTF_Pound)) && (0U == dschar))
344  {
345  cb(buf, count, '0', 1);
346  cb(buf, count, (use_caps ? 'X' : 'x'), 1);
347  vlen += 2U;
348  }
349 #else
350  cb(buf, count, ' ', (int)field_width - (int)vlen);
351 #endif /* PRINTF_ADVANCED_ENABLE */
352  while ('\0' != (*vstrp))
353  {
354  cb(buf, count, *vstrp--, 1);
355  }
356 #if PRINTF_ADVANCED_ENABLE
357  if (0U != (flags_used & (uint32_t)kPRINTF_Minus))
358  {
359  cb(buf, count, ' ', (int)field_width - (int)vlen);
360  }
361 #endif /* PRINTF_ADVANCED_ENABLE */
362 }
363 
364 static uint32_t PrintIsfF(const char c)
365 {
366  uint32_t ret = 0U;
367  if ((c == 'f') || (c == 'F'))
368  {
369  ret = 1U;
370  }
371  return ret;
372 }
373 
374 static uint32_t PrintIsxX(const char c)
375 {
376  uint32_t ret = 0U;
377  if ((c == 'x') || (c == 'X'))
378  {
379  ret = 1U;
380  }
381  return ret;
382 }
383 
384 #if PRINTF_ADVANCED_ENABLE
385 static uint32_t PrintCheckFlags(const char **s)
386 {
387  const char *p = *s;
388  /* First check for specification modifier flags. */
389  uint32_t flags_used = 0U;
390  bool done = false;
391  while (false == done)
392  {
393  switch (*++p)
394  {
395  case '-':
396  flags_used |= (uint32_t)kPRINTF_Minus;
397  break;
398  case '+':
399  flags_used |= (uint32_t)kPRINTF_Plus;
400  break;
401  case ' ':
402  flags_used |= (uint32_t)kPRINTF_Space;
403  break;
404  case '0':
405  flags_used |= (uint32_t)kPRINTF_Zero;
406  break;
407  case '#':
408  flags_used |= (uint32_t)kPRINTF_Pound;
409  break;
410  default:
411  /* We've gone one char too far. */
412  --p;
413  done = true;
414  break;
415  }
416  }
417  *s = p;
418  return flags_used;
419 }
420 #endif /* PRINTF_ADVANCED_ENABLE */
421 
422 #if PRINTF_ADVANCED_ENABLE
423 /*
424  * Check for the length modifier.
425  */
426 static uint32_t PrintGetLengthFlag(const char **s)
427 {
428  const char *p = *s;
429  /* First check for specification modifier flags. */
430  uint32_t flags_used = 0U;
431 
432  switch (/* c = */ *++p)
433  {
434  case 'h':
435  if (*++p != 'h')
436  {
437  flags_used |= (uint32_t)kPRINTF_LengthShortInt;
438  --p;
439  }
440  else
441  {
442  flags_used |= (uint32_t)kPRINTF_LengthChar;
443  }
444  break;
445  case 'l':
446  if (*++p != 'l')
447  {
448  flags_used |= (uint32_t)kPRINTF_LengthLongInt;
449  --p;
450  }
451  else
452  {
453  flags_used |= (uint32_t)kPRINTF_LengthLongLongInt;
454  }
455  break;
456  default:
457  /* we've gone one char too far */
458  --p;
459  break;
460  }
461  *s = p;
462  return flags_used;
463 }
464 #endif /* PRINTF_ADVANCED_ENABLE */
465 
466 static uint8_t PrintGetRadixFromobpu(const char c)
467 {
468  uint8_t radix;
469 
470  if (c == 'o')
471  {
472  radix = 8U;
473  }
474  else if (c == 'b')
475  {
476  radix = 2U;
477  }
478  else if (c == 'p')
479  {
480  radix = 16U;
481  }
482  else
483  {
484  radix = 10U;
485  }
486  return radix;
487 }
488 
489 static uint32_t ScanIsWhiteSpace(const char c)
490 {
491  uint32_t ret = 0U;
492  if ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f'))
493  {
494  ret = 1U;
495  }
496  return ret;
497 }
498 
499 static uint32_t ScanIgnoreWhiteSpace(const char **s)
500 {
501  uint32_t count = 0U;
502  char c;
503 
504  c = **s;
505  while (1U == ScanIsWhiteSpace(c))
506  {
507  count++;
508  (*s)++;
509  c = **s;
510  }
511  return count;
512 }
513 
514 static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
515 {
516 #if PRINTF_ADVANCED_ENABLE
517  int64_t a;
518  int64_t b;
519  int64_t c;
520 
521  uint64_t ua;
522  uint64_t ub;
523  uint64_t uc;
524  uint64_t uc_param;
525 #else
526  int32_t a;
527  int32_t b;
528  int32_t c;
529 
530  uint32_t ua;
531  uint32_t ub;
532  uint32_t uc;
533  uint32_t uc_param;
534 #endif /* PRINTF_ADVANCED_ENABLE */
535 
536  int32_t nlen;
537  char *nstrp;
538 
539  nlen = 0;
540  nstrp = numstr;
541  *nstrp++ = '\0';
542 
543  if (0 != neg)
544  {
545 #if PRINTF_ADVANCED_ENABLE
546  a = *(int64_t *)nump;
547 #else
548  a = *(int32_t *)nump;
549 #endif /* PRINTF_ADVANCED_ENABLE */
550  if (a == 0)
551  {
552  *nstrp = '0';
553  ++nlen;
554  return nlen;
555  }
556  while (a != 0)
557  {
558 #if PRINTF_ADVANCED_ENABLE
559  b = (int64_t)a / (int64_t)radix;
560  c = (int64_t)a - ((int64_t)b * (int64_t)radix);
561  if (c < 0)
562  {
563  uc = (uint64_t)c;
564  uc_param = ~uc;
565  c = (int64_t)uc_param + 1 + (int64_t)'0';
566  }
567 #else
568  b = a / radix;
569  c = a - (b * radix);
570  if (c < 0)
571  {
572  uc = (uint32_t)c;
573  uc_param = ~uc;
574  c = (int32_t)uc_param + 1 + (int32_t)'0';
575  }
576 #endif /* PRINTF_ADVANCED_ENABLE */
577  else
578  {
579  c = c + (int32_t)'0';
580  }
581  a = b;
582  *nstrp++ = (char)c;
583  ++nlen;
584  }
585  }
586  else
587  {
588 #if PRINTF_ADVANCED_ENABLE
589  ua = *(uint64_t *)nump;
590 #else
591  ua = *(uint32_t *)nump;
592 #endif /* PRINTF_ADVANCED_ENABLE */
593  if (ua == 0U)
594  {
595  *nstrp = '0';
596  ++nlen;
597  return nlen;
598  }
599  while (ua != 0U)
600  {
601 #if PRINTF_ADVANCED_ENABLE
602  ub = (uint64_t)ua / (uint64_t)radix;
603  uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix);
604 #else
605  ub = ua / (uint32_t)radix;
606  uc = ua - (ub * (uint32_t)radix);
607 #endif /* PRINTF_ADVANCED_ENABLE */
608 
609  if (uc < 10U)
610  {
611  uc = uc + (uint32_t)'0';
612  }
613  else
614  {
615  uc = uc - 10U + (uint32_t)(use_caps ? 'A' : 'a');
616  }
617  ua = ub;
618  *nstrp++ = (char)uc;
619  ++nlen;
620  }
621  }
622  return nlen;
623 }
624 
625 #if PRINTF_FLOAT_ENABLE
626 static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width)
627 {
628  int32_t a;
629  int32_t b;
630  int32_t c;
631  int32_t i;
632  uint32_t uc;
633  double fa;
634  double dc;
635  double fb;
636  double r;
637  double fractpart;
638  double intpart;
639 
640  int32_t nlen;
641  char *nstrp;
642  nlen = 0;
643  nstrp = numstr;
644  *nstrp++ = '\0';
645  r = *(double *)nump;
646  if (!r)
647  {
648  *nstrp = '0';
649  ++nlen;
650  return nlen;
651  }
652  fractpart = modf((double)r, (double *)&intpart);
653  /* Process fractional part. */
654  for (i = 0; i < precision_width; i++)
655  {
656  fractpart *= radix;
657  }
658  if (r >= 0)
659  {
660  fa = fractpart + (double)0.5;
661  if (fa >= pow(10, precision_width))
662  {
663  intpart++;
664  }
665  }
666  else
667  {
668  fa = fractpart - (double)0.5;
669  if (fa <= -pow(10, precision_width))
670  {
671  intpart--;
672  }
673  }
674  for (i = 0; i < precision_width; i++)
675  {
676  fb = fa / (int32_t)radix;
677  dc = (fa - (int64_t)fb * (int32_t)radix);
678  c = (int32_t)dc;
679  if (c < 0)
680  {
681  uc = (uint32_t)c;
682  c = (int32_t)(~uc) + 1 + '0';
683  }
684  else
685  {
686  c = c + '0';
687  }
688  fa = fb;
689  *nstrp++ = (char)c;
690  ++nlen;
691  }
692  *nstrp++ = (char)'.';
693  ++nlen;
694  a = (int32_t)intpart;
695  if (a == 0)
696  {
697  *nstrp++ = '0';
698  ++nlen;
699  }
700  else
701  {
702  while (a != 0)
703  {
704  b = (int32_t)a / (int32_t)radix;
705  c = (int32_t)a - ((int32_t)b * (int32_t)radix);
706  if (c < 0)
707  {
708  uc = (uint32_t)c;
709  c = (int32_t)(~uc) + 1 + '0';
710  }
711  else
712  {
713  c = c + '0';
714  }
715  a = b;
716  *nstrp++ = (char)c;
717  ++nlen;
718  }
719  }
720  return nlen;
721 }
722 #endif /* PRINTF_FLOAT_ENABLE */
723 
737 int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
738 {
739  /* va_list ap; */
740  const char *p;
741  char c;
742 
743  char vstr[33];
744  char *vstrp = NULL;
745  int32_t vlen = 0;
746 
747  int32_t count = 0;
748 
749  uint32_t field_width;
750  uint32_t precision_width;
751  char *sval;
752  int32_t cval;
753  bool use_caps;
754  uint8_t radix = 0;
755 
756 #if PRINTF_ADVANCED_ENABLE
757  uint32_t flags_used;
758  char schar;
759  int64_t ival;
760  uint64_t uval = 0;
761  bool valid_precision_width;
762 #else
763  int32_t ival;
764  uint32_t uval = 0;
765 #endif /* PRINTF_ADVANCED_ENABLE */
766 
767 #if PRINTF_FLOAT_ENABLE
768  double fval;
769 #endif /* PRINTF_FLOAT_ENABLE */
770 
771  /* Start parsing apart the format string and display appropriate formats and data. */
772  p = fmt;
773  while (true)
774  {
775  if ('\0' == *p)
776  {
777  break;
778  }
779  c = *p;
780  /*
781  * All formats begin with a '%' marker. Special chars like
782  * '\n' or '\t' are normally converted to the appropriate
783  * character by the __compiler__. Thus, no need for this
784  * routine to account for the '\' character.
785  */
786  if (c != '%')
787  {
788  cb(buf, &count, c, 1);
789  p++;
790  /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
791  continue;
792  }
793 
794  use_caps = true;
795 
796 #if PRINTF_ADVANCED_ENABLE
797  /* First check for specification modifier flags. */
798  flags_used = PrintCheckFlags(&p);
799 #endif /* PRINTF_ADVANCED_ENABLE */
800 
801  /* Next check for minimum field width. */
802  field_width = PrintGetWidth(&p, &ap);
803 
804  /* Next check for the width and precision field separator. */
805 #if PRINTF_ADVANCED_ENABLE
806  precision_width = PrintGetPrecision(&p, &ap, &valid_precision_width);
807 #else
808  precision_width = PrintGetPrecision(&p, &ap, NULL);
809  (void)precision_width;
810 #endif
811 
812 #if PRINTF_ADVANCED_ENABLE
813  /* Check for the length modifier. */
814  flags_used |= PrintGetLengthFlag(&p);
815 #endif /* PRINTF_ADVANCED_ENABLE */
816 
817  /* Now we're ready to examine the format. */
818  c = *++p;
819  {
820  if (1U == PrintIsdi(c))
821  {
822 #if PRINTF_ADVANCED_ENABLE
823  if (flags_used & kPRINTF_LengthLongLongInt)
824  {
825  ival = (int64_t)va_arg(ap, int64_t);
826  }
827  else
828 #endif /* PRINTF_ADVANCED_ENABLE */
829  {
830  ival = (int32_t)va_arg(ap, int32_t);
831  }
832  vlen = ConvertRadixNumToString(vstr, (void *)&ival, 1, 10, use_caps);
833  vstrp = &vstr[vlen];
834 #if PRINTF_ADVANCED_ENABLE
835  vlen += PrintGetSignChar(ival, flags_used, &schar);
836  PrintOutputdifFobpu(flags_used, field_width, vlen, schar, vstrp, cb, buf, &count);
837 #else
838  PrintOutputdifFobpu(0U, field_width, (uint32_t)vlen, '\0', vstrp, cb, buf, &count);
839 #endif
840  }
841  else if (1U == PrintIsfF(c))
842  {
843 #if PRINTF_FLOAT_ENABLE
844  fval = (double)va_arg(ap, double);
845  vlen = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
846  vstrp = &vstr[vlen];
847 
848 #if PRINTF_ADVANCED_ENABLE
849  vlen += PrintGetSignChar((int32_t)fval, flags_used, &schar);
850  PrintOutputdifFobpu(flags_used, field_width, vlen, schar, vstrp, cb, buf, &count);
851 #else
852  PrintOutputdifFobpu(0, field_width, vlen, '\0', vstrp, cb, buf, &count);
853 #endif
854 
855 #else
856  (void)va_arg(ap, double);
857 #endif /* PRINTF_FLOAT_ENABLE */
858  }
859  else if (1U == PrintIsxX(c))
860  {
861  if (c == 'x')
862  {
863  use_caps = false;
864  }
865 #if PRINTF_ADVANCED_ENABLE
866  if (flags_used & kPRINTF_LengthLongLongInt)
867  {
868  uval = (uint64_t)va_arg(ap, uint64_t);
869  }
870  else
871 #endif /* PRINTF_ADVANCED_ENABLE */
872  {
873  uval = (uint32_t)va_arg(ap, uint32_t);
874  }
875  vlen = ConvertRadixNumToString(vstr, &uval, 0, 16, use_caps);
876  vstrp = &vstr[vlen];
877 #if PRINTF_ADVANCED_ENABLE
878  PrintOutputxX(flags_used, field_width, vlen, use_caps, vstrp, cb, buf, &count);
879 #else
880  PrintOutputxX(0U, field_width, (uint32_t)vlen, use_caps, vstrp, cb, buf, &count);
881 #endif
882  }
883  else if (1U == PrintIsobpu(c))
884  {
885 #if PRINTF_ADVANCED_ENABLE
886  if (flags_used & kPRINTF_LengthLongLongInt)
887  {
888  uval = (uint64_t)va_arg(ap, uint64_t);
889  }
890  else
891 #endif /* PRINTF_ADVANCED_ENABLE */
892  {
893  uval = (uint32_t)va_arg(ap, uint32_t);
894  }
895 
896  radix = PrintGetRadixFromobpu(c);
897 
898  vlen = ConvertRadixNumToString(vstr, &uval, 0, (int32_t)radix, use_caps);
899  vstrp = &vstr[vlen];
900 #if PRINTF_ADVANCED_ENABLE
901  PrintOutputdifFobpu(flags_used, field_width, vlen, '\0', vstrp, cb, buf, &count);
902 #else
903  PrintOutputdifFobpu(0U, field_width, (uint32_t)vlen, '\0', vstrp, cb, buf, &count);
904 #endif
905  }
906  else if (c == 'c')
907  {
908  cval = (int32_t)va_arg(ap, uint32_t);
909  cb(buf, &count, cval, 1);
910  }
911  else if (c == 's')
912  {
913  sval = (char *)va_arg(ap, char *);
914  if (NULL != sval)
915  {
916 #if PRINTF_ADVANCED_ENABLE
917  if (valid_precision_width)
918  {
919  vlen = precision_width;
920  }
921  else
922  {
923  vlen = strlen(sval);
924  }
925 #else
926  vlen = (int32_t)strlen(sval);
927 #endif /* PRINTF_ADVANCED_ENABLE */
928 #if PRINTF_ADVANCED_ENABLE
929  if (!(flags_used & kPRINTF_Minus))
930 #endif /* PRINTF_ADVANCED_ENABLE */
931  {
932  cb(buf, &count, ' ', (int)field_width - (int)vlen);
933  }
934 
935 #if PRINTF_ADVANCED_ENABLE
936  if (valid_precision_width)
937  {
938  while ((*sval) && (vlen > 0))
939  {
940  cb(buf, &count, *sval++, 1);
941  vlen--;
942  }
943  /* In case that vlen sval is shorter than vlen */
944  vlen = precision_width - vlen;
945  }
946  else
947  {
948 #endif /* PRINTF_ADVANCED_ENABLE */
949  while ('\0' != (*sval))
950  {
951  cb(buf, &count, *sval++, 1);
952  }
953 #if PRINTF_ADVANCED_ENABLE
954  }
955 #endif /* PRINTF_ADVANCED_ENABLE */
956 
957 #if PRINTF_ADVANCED_ENABLE
958  if (flags_used & kPRINTF_Minus)
959  {
960  cb(buf, &count, ' ', field_width - vlen);
961  }
962 #endif /* PRINTF_ADVANCED_ENABLE */
963  }
964  }
965  else
966  {
967  cb(buf, &count, c, 1);
968  }
969  }
970  p++;
971  }
972 
973  return count;
974 }
975 
976 #if SCANF_FLOAT_ENABLE
977 static uint8_t StrFormatScanIsFloat(char *c)
978 {
979  uint8_t ret = 0U;
980  if (('a' == (*c)) || ('A' == (*c)) || ('e' == (*c)) || ('E' == (*c)) || ('f' == (*c)) || ('F' == (*c)) ||
981  ('g' == (*c)) || ('G' == (*c)))
982  {
983  ret = 1U;
984  }
985  return ret;
986 }
987 #endif
988 
989 static uint8_t StrFormatScanIsFormatStarting(char *c)
990 {
991  uint8_t ret = 1U;
992  if ((*c != '%'))
993  {
994  ret = 0U;
995  }
996  else if (*(c + 1) == '%')
997  {
998  ret = 0U;
999  }
1000  else
1001  {
1002  /*MISRA rule 15.7*/
1003  }
1004 
1005  return ret;
1006 }
1007 
1008 static uint8_t StrFormatScanGetBase(uint8_t base, const char *s)
1009 {
1010  if (base == 0U)
1011  {
1012  if (s[0] == '0')
1013  {
1014  if ((s[1] == 'x') || (s[1] == 'X'))
1015  {
1016  base = 16;
1017  }
1018  else
1019  {
1020  base = 8;
1021  }
1022  }
1023  else
1024  {
1025  base = 10;
1026  }
1027  }
1028  return base;
1029 }
1030 
1031 static uint8_t StrFormatScanCheckSymbol(const char *p, int8_t *neg)
1032 {
1033  uint8_t len;
1034  switch (*p)
1035  {
1036  case '-':
1037  *neg = -1;
1038  len = 1;
1039  break;
1040  case '+':
1041  *neg = 1;
1042  len = 1;
1043  break;
1044  default:
1045  *neg = 1;
1046  len = 0;
1047  break;
1048  }
1049  return len;
1050 }
1051 
1052 static uint8_t StrFormatScanFillInteger(uint32_t flag, va_list *args_ptr, int32_t val)
1053 {
1054 #if SCANF_ADVANCED_ENABLE
1055  if ((flag & kSCANF_Suppress))
1056  {
1057  return 0u;
1058  }
1059 
1060  switch (flag & kSCANF_LengthMask)
1061  {
1062  case kSCANF_LengthChar:
1063  if (0 != (flag & (uint32_t)kSCANF_TypeSinged))
1064  {
1065  *va_arg(*args_ptr, signed char *) = (signed char)val;
1066  }
1067  else
1068  {
1069  *va_arg(*args_ptr, unsigned char *) = (unsigned char)val;
1070  }
1071  break;
1072  case kSCANF_LengthShortInt:
1073  if (0 != (flag & (uint32_t)kSCANF_TypeSinged))
1074  {
1075  *va_arg(*args_ptr, signed short *) = (signed short)val;
1076  }
1077  else
1078  {
1079  *va_arg(*args_ptr, unsigned short *) = (unsigned short)val;
1080  }
1081  break;
1082  case kSCANF_LengthLongInt:
1083  if (0 != (flag & (uint32_t)kSCANF_TypeSinged))
1084  {
1085  *va_arg(*args_ptr, signed long int *) = (signed long int)val;
1086  }
1087  else
1088  {
1089  *va_arg(*args_ptr, unsigned long int *) = (unsigned long int)val;
1090  }
1091  break;
1092  case kSCANF_LengthLongLongInt:
1093  if (0 != (flag & (uint32_t)kSCANF_TypeSinged))
1094  {
1095  *va_arg(*args_ptr, signed long long int *) = (signed long long int)val;
1096  }
1097  else
1098  {
1099  *va_arg(*args_ptr, unsigned long long int *) = (unsigned long long int)val;
1100  }
1101  break;
1102  default:
1103  /* The default type is the type int. */
1104  if (0 != (flag & (uint32_t)kSCANF_TypeSinged))
1105  {
1106  *va_arg(*args_ptr, signed int *) = (signed int)val;
1107  }
1108  else
1109  {
1110  *va_arg(*args_ptr, unsigned int *) = (unsigned int)val;
1111  }
1112  break;
1113  }
1114 #else
1115  /* The default type is the type int. */
1116  if (0U != (flag & (uint32_t)kSCANF_TypeSinged))
1117  {
1118  *va_arg(*args_ptr, signed int *) = (signed int)val;
1119  }
1120  else
1121  {
1122  *va_arg(*args_ptr, unsigned int *) = (unsigned int)val;
1123  }
1124 #endif /* SCANF_ADVANCED_ENABLE */
1125 
1126  return 1u;
1127 }
1128 
1129 #if SCANF_FLOAT_ENABLE
1130 static uint8_t StrFormatScanFillFloat(uint32_t flag, va_list *args_ptr, double fnum)
1131 {
1132 #if SCANF_ADVANCED_ENABLE
1133  if (0U != (flag & (uint32_t)kSCANF_Suppress))
1134  {
1135  return 0u;
1136  }
1137  else
1138 #endif /* SCANF_ADVANCED_ENABLE */
1139  {
1140  if (0U != (flag & (uint32_t)kSCANF_LengthLongLongDouble))
1141  {
1142  *va_arg(*args_ptr, double *) = fnum;
1143  }
1144  else
1145  {
1146  *va_arg(*args_ptr, float *) = (float)fnum;
1147  }
1148  return 1u;
1149  }
1150 }
1151 #endif /* SCANF_FLOAT_ENABLE */
1152 
1153 static uint8_t StrFormatScanfStringHandling(char **str, uint32_t *flag, uint32_t *field_width, uint8_t *base)
1154 {
1155  uint8_t exitPending = 0U;
1156  char *c = *str;
1157 
1158  /* Loop to get full conversion specification. */
1159  while (('\0' != (*c)) && (0U == (*flag & (uint32_t)kSCANF_DestMask)))
1160  {
1161 #if SCANF_ADVANCED_ENABLE
1162  if ('*' == (*c))
1163  {
1164  if (0U != ((*flag) & (uint32_t)kSCANF_Suppress))
1165  {
1166  /* Match failure. */
1167  exitPending = 1U;
1168  }
1169  else
1170  {
1171  (*flag) |= (uint32_t)kSCANF_Suppress;
1172  }
1173  }
1174  else if ('h' == (*c))
1175  {
1176  if (0U != ((*flag) & (uint32_t)kSCANF_LengthMask))
1177  {
1178  /* Match failure. */
1179  exitPending = 1U;
1180  }
1181  else
1182  {
1183  if (c[1] == 'h')
1184  {
1185  (*flag) |= (uint32_t)kSCANF_LengthChar;
1186  c++;
1187  }
1188  else
1189  {
1190  (*flag) |= (uint32_t)kSCANF_LengthShortInt;
1191  }
1192  }
1193  }
1194  else if ('l' == (*c))
1195  {
1196  if (0U != ((*flag) & (uint32_t)kSCANF_LengthMask))
1197  {
1198  /* Match failure. */
1199  exitPending = 1U;
1200  }
1201  else
1202  {
1203  if (c[1] == 'l')
1204  {
1205  (*flag) |= (uint32_t)kSCANF_LengthLongLongInt;
1206  c++;
1207  }
1208  else
1209  {
1210  (*flag) |= (uint32_t)kSCANF_LengthLongInt;
1211  }
1212  }
1213  }
1214  else
1215 #endif /* SCANF_ADVANCED_ENABLE */
1216 #if SCANF_FLOAT_ENABLE
1217  if ('L' == (*c))
1218  {
1219  if (0U != ((*flag) & (uint32_t)kSCANF_LengthMask))
1220  {
1221  /* Match failure. */
1222  exitPending = 1U;
1223  }
1224  else
1225  {
1226  (*flag) |= (uint32_t)kSCANF_LengthLongLongDouble;
1227  }
1228  }
1229  else
1230 #endif /* SCANF_FLOAT_ENABLE */
1231  if (((*c) >= '0') && ((*c) <= '9'))
1232  {
1233  {
1234  char *p;
1235  (*field_width) = strtoul(c, &p, 10);
1236  c = p - 1;
1237  }
1238  }
1239  else if ('d' == (*c))
1240  {
1241  (*base) = 10U;
1242  (*flag) |= (uint32_t)kSCANF_TypeSinged;
1243  (*flag) |= (uint32_t)kSCANF_DestInt;
1244  }
1245  else if ('u' == (*c))
1246  {
1247  (*base) = 10U;
1248  (*flag) |= (uint32_t)kSCANF_DestInt;
1249  }
1250  else if ('o' == (*c))
1251  {
1252  (*base) = 8U;
1253  (*flag) |= (uint32_t)kSCANF_DestInt;
1254  }
1255  else if (('x' == (*c)))
1256  {
1257  (*base) = 16U;
1258  (*flag) |= (uint32_t)kSCANF_DestInt;
1259  }
1260  else if ('X' == (*c))
1261  {
1262  (*base) = 16U;
1263  (*flag) |= (uint32_t)kSCANF_DestInt;
1264  }
1265  else if ('i' == (*c))
1266  {
1267  (*base) = 0U;
1268  (*flag) |= (uint32_t)kSCANF_DestInt;
1269  }
1270 #if SCANF_FLOAT_ENABLE
1271  else if (1 == StrFormatScanIsFloat(c))
1272  {
1273  (*flag) |= (uint32_t)kSCANF_DestFloat;
1274  }
1275 #endif /* SCANF_FLOAT_ENABLE */
1276  else if ('c' == (*c))
1277  {
1278  (*flag) |= (uint32_t)kSCANF_DestChar;
1279  if (MAX_FIELD_WIDTH == (*field_width))
1280  {
1281  (*field_width) = 1;
1282  }
1283  }
1284  else if ('s' == (*c))
1285  {
1286  (*flag) |= (uint32_t)kSCANF_DestString;
1287  }
1288  else
1289  {
1290  exitPending = 1U;
1291  }
1292 
1293  if (1U == exitPending)
1294  {
1295  break;
1296  }
1297  else
1298  {
1299  c++;
1300  }
1301  }
1302  *str = c;
1303  return exitPending;
1304 }
1305 
1317 int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
1318 {
1319  uint8_t base;
1320  int8_t neg;
1321  /* Identifier for the format string. */
1322  char *c = format;
1323  char *buf;
1324  /* Flag telling the conversion specification. */
1325  uint32_t flag = 0;
1326  /* Filed width for the matching input streams. */
1327  uint32_t field_width;
1328  /* How many arguments are assigned except the suppress. */
1329  uint32_t nassigned = 0;
1330  /* How many characters are read from the input streams. */
1331  uint32_t n_decode = 0;
1332 
1333  int32_t val;
1334 
1335  uint8_t added;
1336 
1337  uint8_t exitPending = 0;
1338 
1339  const char *s;
1340  /* Identifier for the input string. */
1341  const char *p = line_ptr;
1342 
1343 #if SCANF_FLOAT_ENABLE
1344  double fnum = 0.0;
1345 #endif /* SCANF_FLOAT_ENABLE */
1346  /* Return EOF error before any conversion. */
1347  if (*p == '\0')
1348  {
1349  return -1;
1350  }
1351 
1352  /* Decode directives. */
1353  while (('\0' != (*c)) && ('\0' != (*p)))
1354  {
1355  /* Ignore all white-spaces in the format strings. */
1356  if (0U != ScanIgnoreWhiteSpace((const char **)((void *)&c)))
1357  {
1358  n_decode += ScanIgnoreWhiteSpace(&p);
1359  }
1360  else if (0U == StrFormatScanIsFormatStarting(c))
1361  {
1362  /* Ordinary characters. */
1363  c++;
1364  if (*p == *c)
1365  {
1366  n_decode++;
1367  p++;
1368  c++;
1369  }
1370  else
1371  {
1372  /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
1373  * However, it is deserted now. */
1374  break;
1375  }
1376  }
1377  else
1378  {
1379  /* convernsion specification */
1380  c++;
1381  /* Reset. */
1382  flag = 0;
1383  field_width = MAX_FIELD_WIDTH;
1384  base = 0;
1385  added = 0U;
1386 
1387  exitPending = StrFormatScanfStringHandling(&c, &flag, &field_width, &base);
1388 
1389  if (1U == exitPending)
1390  {
1391  /* Format strings are exhausted. */
1392  break;
1393  }
1394 
1395  /* Matching strings in input streams and assign to argument. */
1396  if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestChar)
1397  {
1398  s = (const char *)p;
1399  buf = va_arg(args_ptr, char *);
1400  while ((0U != (field_width--))
1402  && ('\0' != (*p))
1403 #endif
1404  )
1405  {
1406 #if SCANF_ADVANCED_ENABLE
1407  if (flag & kSCANF_Suppress)
1408  {
1409  p++;
1410  }
1411  else
1412 #endif
1413  {
1414  *buf++ = *p++;
1415 #if SCANF_ADVANCED_ENABLE
1416  added = 1u;
1417 #endif
1418  }
1419  n_decode++;
1420  }
1421 
1422 #if SCANF_ADVANCED_ENABLE
1423  if (1u == added)
1424 #endif
1425  {
1426  nassigned++;
1427  }
1428  }
1429  else if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestString)
1430  {
1431  n_decode += ScanIgnoreWhiteSpace(&p);
1432  s = p;
1433  buf = va_arg(args_ptr, char *);
1434  while ((0U != (field_width--)) && (*p != '\0') && (0U == ScanIsWhiteSpace(*p)))
1435  {
1436 #if SCANF_ADVANCED_ENABLE
1437  if (flag & kSCANF_Suppress)
1438  {
1439  p++;
1440  }
1441  else
1442 #endif
1443  {
1444  *buf++ = *p++;
1445 #if SCANF_ADVANCED_ENABLE
1446  added = 1u;
1447 #endif
1448  }
1449  n_decode++;
1450  }
1451 
1452 #if SCANF_ADVANCED_ENABLE
1453  if (1u == added)
1454 #endif
1455  {
1456  /* Add NULL to end of string. */
1457  *buf = '\0';
1458  nassigned++;
1459  }
1460  }
1461  else if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestInt)
1462  {
1463  n_decode += ScanIgnoreWhiteSpace(&p);
1464  s = p;
1465  val = 0;
1466  base = StrFormatScanGetBase(base, s);
1467 
1468  added = StrFormatScanCheckSymbol(p, &neg);
1469  n_decode += added;
1470  p += added;
1471  field_width -= added;
1472 
1473  s = p;
1474  if (strlen(p) > field_width)
1475  {
1476  char temp[12];
1477  char *tempEnd;
1478  (void)memcpy(temp, p, sizeof(temp) - 1U);
1479  temp[sizeof(temp) - 1U] = '\0';
1480  val = (int32_t)strtoul(temp, &tempEnd, (int)base);
1481  p = p + (tempEnd - temp);
1482  }
1483  else
1484  {
1485  char *tempEnd;
1486  val = (int32_t)strtoul(p, &tempEnd, (int)base);
1487  p = tempEnd;
1488  }
1489  n_decode += (uint32_t)p - (uint32_t)s;
1490 
1491  val *= neg;
1492 
1493  nassigned += StrFormatScanFillInteger(flag, &args_ptr, val);
1494  }
1495 #if SCANF_FLOAT_ENABLE
1496  else if ((flag & kSCANF_DestMask) == kSCANF_DestFloat)
1497  {
1498  n_decode += ScanIgnoreWhiteSpace(&p);
1499  fnum = strtod(p, (char **)&s);
1500 
1501  if ((fnum < HUGE_VAL) && (fnum > -HUGE_VAL))
1502  {
1503  n_decode += (int)(s) - (int)(p);
1504  p = s;
1505  nassigned += StrFormatScanFillFloat(flag, &args_ptr, fnum);
1506  }
1507  }
1508 #endif /* SCANF_FLOAT_ENABLE */
1509  else
1510  {
1511  break;
1512  }
1513  }
1514  }
1515  return (int)nassigned;
1516 }
StrFormatScanFillInteger
static uint8_t StrFormatScanFillInteger(uint32_t flag, va_list *args_ptr, int32_t val)
Definition: fsl_str.c:1052
StrFormatScanGetBase
static uint8_t StrFormatScanGetBase(uint8_t base, const char *s)
Definition: fsl_str.c:1008
_debugconsole_scanf_flag
_debugconsole_scanf_flag
Specification modifier flags for scanf.
Definition: fsl_str.c:45
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
s
XmlRpcServer s
MAX_FIELD_WIDTH
#define MAX_FIELD_WIDTH
Definition: fsl_str.c:25
kSCANF_DestFloat
@ kSCANF_DestFloat
Definition: fsl_str.c:53
fsl_str.h
fsl_debug_console_conf.h
kSCANF_DestInt
@ kSCANF_DestInt
Definition: fsl_str.c:52
kSCANF_DestSet
@ kSCANF_DestSet
Definition: fsl_str.c:51
PrintIsxX
static uint32_t PrintIsxX(const char c)
Definition: fsl_str.c:374
ScanIsWhiteSpace
static uint32_t ScanIsWhiteSpace(const char c)
Definition: fsl_str.c:489
kSCANF_Suppress
@ kSCANF_Suppress
Definition: fsl_str.c:47
PrintIsfF
static uint32_t PrintIsfF(const char c)
Definition: fsl_str.c:364
kSCANF_DestString
@ kSCANF_DestString
Definition: fsl_str.c:50
PrintGetRadixFromobpu
static uint8_t PrintGetRadixFromobpu(const char c)
Definition: fsl_str.c:466
kSCANF_LengthMask
@ kSCANF_LengthMask
Definition: fsl_str.c:54
StrFormatScanf
int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
Converts an input line of ASCII characters based upon a provided string format.
Definition: fsl_str.c:1317
kSCANF_DestChar
@ kSCANF_DestChar
Definition: fsl_str.c:49
ConvertRadixNumToString
static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
Converts a radix number to a string and return its length.
Definition: fsl_str.c:514
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
PrintOutputxX
static void PrintOutputxX(uint32_t flags_used, uint32_t field_width, uint32_t vlen, bool use_caps, char *vstrp, printfCb cb, char *buf, int32_t *count)
Definition: fsl_str.c:303
kSCANF_TypeSinged
@ kSCANF_TypeSinged
Definition: fsl_str.c:64
PrintIsdi
static uint32_t PrintIsdi(const char c)
Definition: fsl_str.c:240
StrFormatScanCheckSymbol
static uint8_t StrFormatScanCheckSymbol(const char *p, int8_t *neg)
Definition: fsl_str.c:1031
printfCb
void(* printfCb)(char *buf, int32_t *indicator, char val, int len)
A function pointer which is used when format printf log.
Definition: fsl_str.h:30
HUGE_VAL
#define HUGE_VAL
The overflow value.
Definition: fsl_str.c:21
StrFormatScanIsFormatStarting
static uint8_t StrFormatScanIsFormatStarting(char *c)
Definition: fsl_str.c:989
PrintGetWidth
static uint32_t PrintGetWidth(const char **p, va_list *ap)
Definition: fsl_str.c:144
kSCANF_DestMask
@ kSCANF_DestMask
Definition: fsl_str.c:48
PrintGetPrecision
static uint32_t PrintGetPrecision(const char **s, va_list *ap, bool *valid_precision_width)
Definition: fsl_str.c:173
ScanIgnoreWhiteSpace
static uint32_t ScanIgnoreWhiteSpace(const char **s)
Keil: suppress ellipsis warning in va_arg usage below.
Definition: fsl_str.c:499
PrintIsobpu
static uint32_t PrintIsobpu(const char c)
Definition: fsl_str.c:230
StrFormatPrintf
int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
This function outputs its parameters according to a formatted string.
Definition: fsl_str.c:737
StrFormatScanfStringHandling
static uint8_t StrFormatScanfStringHandling(char **str, uint32_t *flag, uint32_t *field_width, uint8_t *base)
Definition: fsl_str.c:1153
PrintOutputdifFobpu
static void PrintOutputdifFobpu(uint32_t flags_used, uint32_t field_width, uint32_t vlen, char schar, char *vstrp, printfCb cb, char *buf, int32_t *count)
Definition: fsl_str.c:250
SCANF_ADVANCED_ENABLE
#define SCANF_ADVANCED_ENABLE
Definition to support advanced format specifier for scanf.
Definition: fsl_debug_console_conf.h:151


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:56