fsl_str.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /*
  2. * Copyright 2017 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. * Definitions
  16. ******************************************************************************/
  17. /*! @brief The overflow value.*/
  18. #ifndef HUGE_VAL
  19. #define HUGE_VAL (99.e99)
  20. #endif /* HUGE_VAL */
  21. #if PRINTF_ADVANCED_ENABLE
  22. /*! @brief Specification modifier flags for printf. */
  23. enum _debugconsole_printf_flag
  24. {
  25. kPRINTF_Minus = 0x01U, /*!< Minus FLag. */
  26. kPRINTF_Plus = 0x02U, /*!< Plus Flag. */
  27. kPRINTF_Space = 0x04U, /*!< Space Flag. */
  28. kPRINTF_Zero = 0x08U, /*!< Zero Flag. */
  29. kPRINTF_Pound = 0x10U, /*!< Pound Flag. */
  30. kPRINTF_LengthChar = 0x20U, /*!< Length: Char Flag. */
  31. kPRINTF_LengthShortInt = 0x40U, /*!< Length: Short Int Flag. */
  32. kPRINTF_LengthLongInt = 0x80U, /*!< Length: Long Int Flag. */
  33. kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */
  34. };
  35. #endif /* PRINTF_ADVANCED_ENABLE */
  36. /*! @brief Specification modifier flags for scanf. */
  37. enum _debugconsole_scanf_flag
  38. {
  39. kSCANF_Suppress = 0x2U, /*!< Suppress Flag. */
  40. kSCANF_DestMask = 0x7cU, /*!< Destination Mask. */
  41. kSCANF_DestChar = 0x4U, /*!< Destination Char Flag. */
  42. kSCANF_DestString = 0x8U, /*!< Destination String FLag. */
  43. kSCANF_DestSet = 0x10U, /*!< Destination Set Flag. */
  44. kSCANF_DestInt = 0x20U, /*!< Destination Int Flag. */
  45. kSCANF_DestFloat = 0x30U, /*!< Destination Float Flag. */
  46. kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */
  47. #if SCANF_ADVANCED_ENABLE
  48. kSCANF_LengthChar = 0x100U, /*!< Length Char Flag. */
  49. kSCANF_LengthShortInt = 0x200U, /*!< Length ShortInt Flag. */
  50. kSCANF_LengthLongInt = 0x400U, /*!< Length LongInt Flag. */
  51. kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */
  52. #endif /* SCANF_ADVANCED_ENABLE */
  53. #if SCANF_FLOAT_ENABLE
  54. kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */
  55. #endif /*PRINTF_FLOAT_ENABLE */
  56. kSCANF_TypeSinged = 0x2000U, /*!< TypeSinged Flag. */
  57. };
  58. /*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
  59. #if defined(__CC_ARM)
  60. #pragma diag_suppress 1256
  61. #endif /* __CC_ARM */
  62. /*******************************************************************************
  63. * Prototypes
  64. ******************************************************************************/
  65. /*!
  66. * @brief Scanline function which ignores white spaces.
  67. *
  68. * @param[in] s The address of the string pointer to update.
  69. * @return String without white spaces.
  70. */
  71. static uint32_t ScanIgnoreWhiteSpace(const char **s);
  72. /*!
  73. * @brief Converts a radix number to a string and return its length.
  74. *
  75. * @param[in] numstr Converted string of the number.
  76. * @param[in] nump Pointer to the number.
  77. * @param[in] neg Polarity of the number.
  78. * @param[in] radix The radix to be converted to.
  79. * @param[in] use_caps Used to identify %x/X output format.
  80. * @return Length of the converted string.
  81. */
  82. static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps);
  83. #if PRINTF_FLOAT_ENABLE
  84. /*!
  85. * @brief Converts a floating radix number to a string and return its length.
  86. *
  87. * @param[in] numstr Converted string of the number.
  88. * @param[in] nump Pointer to the number.
  89. * @param[in] radix The radix to be converted to.
  90. * @param[in] precision_width Specify the precision width.
  91. * @return Length of the converted string.
  92. */
  93. static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width);
  94. #endif /* PRINTF_FLOAT_ENABLE */
  95. /*!
  96. *
  97. */
  98. double modf(double input_dbl, double *intpart_ptr);
  99. /*************Code for process formatted data*******************************/
  100. static uint32_t ScanIgnoreWhiteSpace(const char **s)
  101. {
  102. uint8_t count = 0;
  103. uint8_t c;
  104. c = **s;
  105. while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f'))
  106. {
  107. count++;
  108. (*s)++;
  109. c = **s;
  110. }
  111. return count;
  112. }
  113. static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
  114. {
  115. #if PRINTF_ADVANCED_ENABLE
  116. int64_t a;
  117. int64_t b;
  118. int64_t c;
  119. uint64_t ua;
  120. uint64_t ub;
  121. uint64_t uc;
  122. #else
  123. int32_t a;
  124. int32_t b;
  125. int32_t c;
  126. uint32_t ua;
  127. uint32_t ub;
  128. uint32_t uc;
  129. #endif /* PRINTF_ADVANCED_ENABLE */
  130. int32_t nlen;
  131. char *nstrp;
  132. nlen = 0;
  133. nstrp = numstr;
  134. *nstrp++ = '\0';
  135. if (neg)
  136. {
  137. #if PRINTF_ADVANCED_ENABLE
  138. a = *(int64_t *)nump;
  139. #else
  140. a = *(int32_t *)nump;
  141. #endif /* PRINTF_ADVANCED_ENABLE */
  142. if (a == 0)
  143. {
  144. *nstrp = '0';
  145. ++nlen;
  146. return nlen;
  147. }
  148. while (a != 0)
  149. {
  150. #if PRINTF_ADVANCED_ENABLE
  151. b = (int64_t)a / (int64_t)radix;
  152. c = (int64_t)a - ((int64_t)b * (int64_t)radix);
  153. if (c < 0)
  154. {
  155. uc = (uint64_t)c;
  156. c = (int64_t)(~uc) + 1 + '0';
  157. }
  158. #else
  159. b = a / radix;
  160. c = a - (b * radix);
  161. if (c < 0)
  162. {
  163. uc = (uint32_t)c;
  164. c = (uint32_t)(~uc) + 1 + '0';
  165. }
  166. #endif /* PRINTF_ADVANCED_ENABLE */
  167. else
  168. {
  169. c = c + '0';
  170. }
  171. a = b;
  172. *nstrp++ = (char)c;
  173. ++nlen;
  174. }
  175. }
  176. else
  177. {
  178. #if PRINTF_ADVANCED_ENABLE
  179. ua = *(uint64_t *)nump;
  180. #else
  181. ua = *(uint32_t *)nump;
  182. #endif /* PRINTF_ADVANCED_ENABLE */
  183. if (ua == 0)
  184. {
  185. *nstrp = '0';
  186. ++nlen;
  187. return nlen;
  188. }
  189. while (ua != 0)
  190. {
  191. #if PRINTF_ADVANCED_ENABLE
  192. ub = (uint64_t)ua / (uint64_t)radix;
  193. uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix);
  194. #else
  195. ub = ua / (uint32_t)radix;
  196. uc = ua - (ub * (uint32_t)radix);
  197. #endif /* PRINTF_ADVANCED_ENABLE */
  198. if (uc < 10)
  199. {
  200. uc = uc + '0';
  201. }
  202. else
  203. {
  204. uc = uc - 10 + (use_caps ? 'A' : 'a');
  205. }
  206. ua = ub;
  207. *nstrp++ = (char)uc;
  208. ++nlen;
  209. }
  210. }
  211. return nlen;
  212. }
  213. #if PRINTF_FLOAT_ENABLE
  214. static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width)
  215. {
  216. int32_t a;
  217. int32_t b;
  218. int32_t c;
  219. int32_t i;
  220. uint32_t uc;
  221. double fa;
  222. double dc;
  223. double fb;
  224. double r;
  225. double fractpart;
  226. double intpart;
  227. int32_t nlen;
  228. char *nstrp;
  229. nlen = 0;
  230. nstrp = numstr;
  231. *nstrp++ = '\0';
  232. r = *(double *)nump;
  233. if (!r)
  234. {
  235. *nstrp = '0';
  236. ++nlen;
  237. return nlen;
  238. }
  239. fractpart = modf((double)r, (double *)&intpart);
  240. /* Process fractional part. */
  241. for (i = 0; i < precision_width; i++)
  242. {
  243. fractpart *= radix;
  244. }
  245. if (r >= 0)
  246. {
  247. fa = fractpart + (double)0.5;
  248. if (fa >= pow(10, precision_width))
  249. {
  250. intpart++;
  251. }
  252. }
  253. else
  254. {
  255. fa = fractpart - (double)0.5;
  256. if (fa <= -pow(10, precision_width))
  257. {
  258. intpart--;
  259. }
  260. }
  261. for (i = 0; i < precision_width; i++)
  262. {
  263. fb = fa / (int32_t)radix;
  264. dc = (fa - (int64_t)fb * (int32_t)radix);
  265. c = (int32_t)dc;
  266. if (c < 0)
  267. {
  268. uc = (uint32_t)c;
  269. c = (int32_t)(~uc) + 1 + '0';
  270. }
  271. else
  272. {
  273. c = c + '0';
  274. }
  275. fa = fb;
  276. *nstrp++ = (char)c;
  277. ++nlen;
  278. }
  279. *nstrp++ = (char)'.';
  280. ++nlen;
  281. a = (int32_t)intpart;
  282. if (a == 0)
  283. {
  284. *nstrp++ = '0';
  285. ++nlen;
  286. }
  287. else
  288. {
  289. while (a != 0)
  290. {
  291. b = (int32_t)a / (int32_t)radix;
  292. c = (int32_t)a - ((int32_t)b * (int32_t)radix);
  293. if (c < 0)
  294. {
  295. uc = (uint32_t)c;
  296. c = (int32_t)(~uc) + 1 + '0';
  297. }
  298. else
  299. {
  300. c = c + '0';
  301. }
  302. a = b;
  303. *nstrp++ = (char)c;
  304. ++nlen;
  305. }
  306. }
  307. return nlen;
  308. }
  309. #endif /* PRINTF_FLOAT_ENABLE */
  310. /*!
  311. * brief This function outputs its parameters according to a formatted string.
  312. *
  313. * note I/O is performed by calling given function pointer using following
  314. * (*func_ptr)(c);
  315. *
  316. * param[in] fmt_ptr Format string for printf.
  317. * param[in] args_ptr Arguments to printf.
  318. * param[in] buf pointer to the buffer
  319. * param cb print callback function pointer
  320. *
  321. * return Number of characters to be print
  322. */
  323. int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
  324. {
  325. /* va_list ap; */
  326. char *p;
  327. int32_t c;
  328. char vstr[33];
  329. char *vstrp = NULL;
  330. int32_t vlen = 0;
  331. int32_t done;
  332. int32_t count = 0;
  333. uint32_t field_width;
  334. uint32_t precision_width;
  335. char *sval;
  336. int32_t cval;
  337. bool use_caps;
  338. uint8_t radix = 0;
  339. #if PRINTF_ADVANCED_ENABLE
  340. uint32_t flags_used;
  341. int32_t schar, dschar;
  342. int64_t ival;
  343. uint64_t uval = 0;
  344. bool valid_precision_width;
  345. #else
  346. int32_t ival;
  347. uint32_t uval = 0;
  348. #endif /* PRINTF_ADVANCED_ENABLE */
  349. #if PRINTF_FLOAT_ENABLE
  350. double fval;
  351. #endif /* PRINTF_FLOAT_ENABLE */
  352. /* Start parsing apart the format string and display appropriate formats and data. */
  353. for (p = (char *)fmt; (c = *p) != 0; p++)
  354. {
  355. /*
  356. * All formats begin with a '%' marker. Special chars like
  357. * '\n' or '\t' are normally converted to the appropriate
  358. * character by the __compiler__. Thus, no need for this
  359. * routine to account for the '\' character.
  360. */
  361. if (c != '%')
  362. {
  363. cb(buf, &count, c, 1);
  364. /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
  365. continue;
  366. }
  367. use_caps = true;
  368. #if PRINTF_ADVANCED_ENABLE
  369. /* First check for specification modifier flags. */
  370. flags_used = 0;
  371. done = false;
  372. while (!done)
  373. {
  374. switch (*++p)
  375. {
  376. case '-':
  377. flags_used |= kPRINTF_Minus;
  378. break;
  379. case '+':
  380. flags_used |= kPRINTF_Plus;
  381. break;
  382. case ' ':
  383. flags_used |= kPRINTF_Space;
  384. break;
  385. case '0':
  386. flags_used |= kPRINTF_Zero;
  387. break;
  388. case '#':
  389. flags_used |= kPRINTF_Pound;
  390. break;
  391. default:
  392. /* We've gone one char too far. */
  393. --p;
  394. done = true;
  395. break;
  396. }
  397. }
  398. #endif /* PRINTF_ADVANCED_ENABLE */
  399. /* Next check for minimum field width. */
  400. field_width = 0;
  401. done = false;
  402. while (!done)
  403. {
  404. c = *++p;
  405. if ((c >= '0') && (c <= '9'))
  406. {
  407. field_width = (field_width * 10) + (c - '0');
  408. }
  409. #if PRINTF_ADVANCED_ENABLE
  410. else if (c == '*')
  411. {
  412. field_width = (uint32_t)va_arg(ap, uint32_t);
  413. }
  414. #endif /* PRINTF_ADVANCED_ENABLE */
  415. else
  416. {
  417. /* We've gone one char too far. */
  418. --p;
  419. done = true;
  420. }
  421. }
  422. /* Next check for the width and precision field separator. */
  423. precision_width = 6;
  424. #if PRINTF_ADVANCED_ENABLE
  425. valid_precision_width = false;
  426. #endif /* PRINTF_ADVANCED_ENABLE */
  427. if (*++p == '.')
  428. {
  429. /* Must get precision field width, if present. */
  430. precision_width = 0;
  431. done = false;
  432. while (!done)
  433. {
  434. c = *++p;
  435. if ((c >= '0') && (c <= '9'))
  436. {
  437. precision_width = (precision_width * 10) + (c - '0');
  438. #if PRINTF_ADVANCED_ENABLE
  439. valid_precision_width = true;
  440. #endif /* PRINTF_ADVANCED_ENABLE */
  441. }
  442. #if PRINTF_ADVANCED_ENABLE
  443. else if (c == '*')
  444. {
  445. precision_width = (uint32_t)va_arg(ap, uint32_t);
  446. valid_precision_width = true;
  447. }
  448. #endif /* PRINTF_ADVANCED_ENABLE */
  449. else
  450. {
  451. /* We've gone one char too far. */
  452. --p;
  453. done = true;
  454. }
  455. }
  456. }
  457. else
  458. {
  459. /* We've gone one char too far. */
  460. --p;
  461. }
  462. #if PRINTF_ADVANCED_ENABLE
  463. /*
  464. * Check for the length modifier.
  465. */
  466. switch (/* c = */ *++p)
  467. {
  468. case 'h':
  469. if (*++p != 'h')
  470. {
  471. flags_used |= kPRINTF_LengthShortInt;
  472. --p;
  473. }
  474. else
  475. {
  476. flags_used |= kPRINTF_LengthChar;
  477. }
  478. break;
  479. case 'l':
  480. if (*++p != 'l')
  481. {
  482. flags_used |= kPRINTF_LengthLongInt;
  483. --p;
  484. }
  485. else
  486. {
  487. flags_used |= kPRINTF_LengthLongLongInt;
  488. }
  489. break;
  490. default:
  491. /* we've gone one char too far */
  492. --p;
  493. break;
  494. }
  495. #endif /* PRINTF_ADVANCED_ENABLE */
  496. /* Now we're ready to examine the format. */
  497. c = *++p;
  498. {
  499. if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') ||
  500. (c == 'b') || (c == 'p') || (c == 'u'))
  501. {
  502. if ((c == 'd') || (c == 'i'))
  503. {
  504. #if PRINTF_ADVANCED_ENABLE
  505. if (flags_used & kPRINTF_LengthLongLongInt)
  506. {
  507. ival = (int64_t)va_arg(ap, int64_t);
  508. }
  509. else
  510. #endif /* PRINTF_ADVANCED_ENABLE */
  511. {
  512. ival = (int32_t)va_arg(ap, int32_t);
  513. }
  514. vlen = ConvertRadixNumToString(vstr, &ival, true, 10, use_caps);
  515. vstrp = &vstr[vlen];
  516. #if PRINTF_ADVANCED_ENABLE
  517. if (ival < 0)
  518. {
  519. schar = '-';
  520. ++vlen;
  521. }
  522. else
  523. {
  524. if (flags_used & kPRINTF_Plus)
  525. {
  526. schar = '+';
  527. ++vlen;
  528. }
  529. else
  530. {
  531. if (flags_used & kPRINTF_Space)
  532. {
  533. schar = ' ';
  534. ++vlen;
  535. }
  536. else
  537. {
  538. schar = 0;
  539. }
  540. }
  541. }
  542. dschar = false;
  543. /* Do the ZERO pad. */
  544. if (flags_used & kPRINTF_Zero)
  545. {
  546. if (schar)
  547. {
  548. cb(buf, &count, schar, 1);
  549. }
  550. dschar = true;
  551. cb(buf, &count, '0', field_width - vlen);
  552. vlen = field_width;
  553. }
  554. else
  555. {
  556. if (!(flags_used & kPRINTF_Minus))
  557. {
  558. cb(buf, &count, ' ', field_width - vlen);
  559. if (schar)
  560. {
  561. cb(buf, &count, schar, 1);
  562. }
  563. dschar = true;
  564. }
  565. }
  566. /* The string was built in reverse order, now display in correct order. */
  567. if ((!dschar) && schar)
  568. {
  569. cb(buf, &count, schar, 1);
  570. }
  571. #endif /* PRINTF_ADVANCED_ENABLE */
  572. }
  573. #if PRINTF_FLOAT_ENABLE
  574. if ((c == 'f') || (c == 'F'))
  575. {
  576. fval = (double)va_arg(ap, double);
  577. vlen = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
  578. vstrp = &vstr[vlen];
  579. #if PRINTF_ADVANCED_ENABLE
  580. if (fval < 0)
  581. {
  582. schar = '-';
  583. ++vlen;
  584. }
  585. else
  586. {
  587. if (flags_used & kPRINTF_Plus)
  588. {
  589. schar = '+';
  590. ++vlen;
  591. }
  592. else
  593. {
  594. if (flags_used & kPRINTF_Space)
  595. {
  596. schar = ' ';
  597. ++vlen;
  598. }
  599. else
  600. {
  601. schar = 0;
  602. }
  603. }
  604. }
  605. dschar = false;
  606. if (flags_used & kPRINTF_Zero)
  607. {
  608. if (schar)
  609. {
  610. cb(buf, &count, schar, 1);
  611. }
  612. dschar = true;
  613. cb(buf, &count, '0', field_width - vlen);
  614. vlen = field_width;
  615. }
  616. else
  617. {
  618. if (!(flags_used & kPRINTF_Minus))
  619. {
  620. cb(buf, &count, ' ', field_width - vlen);
  621. if (schar)
  622. {
  623. cb(buf, &count, schar, 1);
  624. }
  625. dschar = true;
  626. }
  627. }
  628. if ((!dschar) && schar)
  629. {
  630. cb(buf, &count, schar, 1);
  631. }
  632. #endif /* PRINTF_ADVANCED_ENABLE */
  633. }
  634. #endif /* PRINTF_FLOAT_ENABLE */
  635. if ((c == 'X') || (c == 'x'))
  636. {
  637. if (c == 'x')
  638. {
  639. use_caps = false;
  640. }
  641. #if PRINTF_ADVANCED_ENABLE
  642. if (flags_used & kPRINTF_LengthLongLongInt)
  643. {
  644. uval = (uint64_t)va_arg(ap, uint64_t);
  645. }
  646. else
  647. #endif /* PRINTF_ADVANCED_ENABLE */
  648. {
  649. uval = (uint32_t)va_arg(ap, uint32_t);
  650. }
  651. vlen = ConvertRadixNumToString(vstr, &uval, false, 16, use_caps);
  652. vstrp = &vstr[vlen];
  653. #if PRINTF_ADVANCED_ENABLE
  654. dschar = false;
  655. if (flags_used & kPRINTF_Zero)
  656. {
  657. if (flags_used & kPRINTF_Pound)
  658. {
  659. cb(buf, &count, '0', 1);
  660. cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
  661. dschar = true;
  662. }
  663. cb(buf, &count, '0', field_width - vlen);
  664. vlen = field_width;
  665. }
  666. else
  667. {
  668. if (!(flags_used & kPRINTF_Minus))
  669. {
  670. if (flags_used & kPRINTF_Pound)
  671. {
  672. vlen += 2;
  673. }
  674. cb(buf, &count, ' ', field_width - vlen);
  675. if (flags_used & kPRINTF_Pound)
  676. {
  677. cb(buf, &count, '0', 1);
  678. cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
  679. dschar = true;
  680. }
  681. }
  682. }
  683. if ((flags_used & kPRINTF_Pound) && (!dschar))
  684. {
  685. cb(buf, &count, '0', 1);
  686. cb(buf, &count, (use_caps ? 'X' : 'x'), 1);
  687. vlen += 2;
  688. }
  689. #endif /* PRINTF_ADVANCED_ENABLE */
  690. }
  691. if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
  692. {
  693. #if PRINTF_ADVANCED_ENABLE
  694. if (flags_used & kPRINTF_LengthLongLongInt)
  695. {
  696. uval = (uint64_t)va_arg(ap, uint64_t);
  697. }
  698. else
  699. #endif /* PRINTF_ADVANCED_ENABLE */
  700. {
  701. uval = (uint32_t)va_arg(ap, uint32_t);
  702. }
  703. if (c == 'o')
  704. {
  705. radix = 8;
  706. }
  707. else if (c == 'b')
  708. {
  709. radix = 2;
  710. }
  711. else if (c == 'p')
  712. {
  713. radix = 16;
  714. }
  715. else
  716. {
  717. radix = 10;
  718. }
  719. vlen = ConvertRadixNumToString(vstr, &uval, false, radix, use_caps);
  720. vstrp = &vstr[vlen];
  721. #if PRINTF_ADVANCED_ENABLE
  722. if (flags_used & kPRINTF_Zero)
  723. {
  724. cb(buf, &count, '0', field_width - vlen);
  725. vlen = field_width;
  726. }
  727. else
  728. {
  729. if (!(flags_used & kPRINTF_Minus))
  730. {
  731. cb(buf, &count, ' ', field_width - vlen);
  732. }
  733. }
  734. #endif /* PRINTF_ADVANCED_ENABLE */
  735. }
  736. #if !PRINTF_ADVANCED_ENABLE
  737. cb(buf, &count, ' ', field_width - vlen);
  738. #endif /* !PRINTF_ADVANCED_ENABLE */
  739. if (vstrp != NULL)
  740. {
  741. while (*vstrp)
  742. {
  743. cb(buf, &count, *vstrp--, 1);
  744. }
  745. }
  746. #if PRINTF_ADVANCED_ENABLE
  747. if (flags_used & kPRINTF_Minus)
  748. {
  749. cb(buf, &count, ' ', field_width - vlen);
  750. }
  751. #endif /* PRINTF_ADVANCED_ENABLE */
  752. }
  753. else if (c == 'c')
  754. {
  755. cval = (char)va_arg(ap, uint32_t);
  756. cb(buf, &count, cval, 1);
  757. }
  758. else if (c == 's')
  759. {
  760. sval = (char *)va_arg(ap, char *);
  761. if (sval)
  762. {
  763. #if PRINTF_ADVANCED_ENABLE
  764. if (valid_precision_width)
  765. {
  766. vlen = precision_width;
  767. }
  768. else
  769. {
  770. vlen = strlen(sval);
  771. }
  772. #else
  773. vlen = strlen(sval);
  774. #endif /* PRINTF_ADVANCED_ENABLE */
  775. #if PRINTF_ADVANCED_ENABLE
  776. if (!(flags_used & kPRINTF_Minus))
  777. #endif /* PRINTF_ADVANCED_ENABLE */
  778. {
  779. cb(buf, &count, ' ', field_width - vlen);
  780. }
  781. #if PRINTF_ADVANCED_ENABLE
  782. if (valid_precision_width)
  783. {
  784. while ((*sval) && (vlen > 0))
  785. {
  786. cb(buf, &count, *sval++, 1);
  787. vlen--;
  788. }
  789. /* In case that vlen sval is shorter than vlen */
  790. vlen = precision_width - vlen;
  791. }
  792. else
  793. {
  794. #endif /* PRINTF_ADVANCED_ENABLE */
  795. while (*sval)
  796. {
  797. cb(buf, &count, *sval++, 1);
  798. }
  799. #if PRINTF_ADVANCED_ENABLE
  800. }
  801. #endif /* PRINTF_ADVANCED_ENABLE */
  802. #if PRINTF_ADVANCED_ENABLE
  803. if (flags_used & kPRINTF_Minus)
  804. {
  805. cb(buf, &count, ' ', field_width - vlen);
  806. }
  807. #endif /* PRINTF_ADVANCED_ENABLE */
  808. }
  809. }
  810. else
  811. {
  812. cb(buf, &count, c, 1);
  813. }
  814. }
  815. }
  816. return count;
  817. }
  818. /*!
  819. * brief Converts an input line of ASCII characters based upon a provided
  820. * string format.
  821. *
  822. * param[in] line_ptr The input line of ASCII data.
  823. * param[in] format Format first points to the format string.
  824. * param[in] args_ptr The list of parameters.
  825. *
  826. * return Number of input items converted and assigned.
  827. * retval IO_EOF When line_ptr is empty string "".
  828. */
  829. int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
  830. {
  831. uint8_t base;
  832. int8_t neg;
  833. /* Identifier for the format string. */
  834. char *c = format;
  835. char temp;
  836. char *buf;
  837. /* Flag telling the conversion specification. */
  838. uint32_t flag = 0;
  839. /* Filed width for the matching input streams. */
  840. uint32_t field_width;
  841. /* How many arguments are assigned except the suppress. */
  842. uint32_t nassigned = 0;
  843. /* How many characters are read from the input streams. */
  844. uint32_t n_decode = 0;
  845. int32_t val;
  846. const char *s;
  847. /* Identifier for the input string. */
  848. const char *p = line_ptr;
  849. #if SCANF_FLOAT_ENABLE
  850. double fnum = 0.0;
  851. #endif /* SCANF_FLOAT_ENABLE */
  852. /* Return EOF error before any conversion. */
  853. if (*p == '\0')
  854. {
  855. return -1;
  856. }
  857. /* Decode directives. */
  858. while ((*c) && (*p))
  859. {
  860. /* Ignore all white-spaces in the format strings. */
  861. if (ScanIgnoreWhiteSpace((const char **)&c))
  862. {
  863. n_decode += ScanIgnoreWhiteSpace(&p);
  864. }
  865. else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%')))
  866. {
  867. /* Ordinary characters. */
  868. c++;
  869. if (*p == *c)
  870. {
  871. n_decode++;
  872. p++;
  873. c++;
  874. }
  875. else
  876. {
  877. /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
  878. * However, it is deserted now. */
  879. break;
  880. }
  881. }
  882. else
  883. {
  884. /* convernsion specification */
  885. c++;
  886. /* Reset. */
  887. flag = 0;
  888. field_width = 0;
  889. base = 0;
  890. /* Loop to get full conversion specification. */
  891. while ((*c) && (!(flag & kSCANF_DestMask)))
  892. {
  893. switch (*c)
  894. {
  895. #if SCANF_ADVANCED_ENABLE
  896. case '*':
  897. if (flag & kSCANF_Suppress)
  898. {
  899. /* Match failure. */
  900. return nassigned;
  901. }
  902. flag |= kSCANF_Suppress;
  903. c++;
  904. break;
  905. case 'h':
  906. if (flag & kSCANF_LengthMask)
  907. {
  908. /* Match failure. */
  909. return nassigned;
  910. }
  911. if (c[1] == 'h')
  912. {
  913. flag |= kSCANF_LengthChar;
  914. c++;
  915. }
  916. else
  917. {
  918. flag |= kSCANF_LengthShortInt;
  919. }
  920. c++;
  921. break;
  922. case 'l':
  923. if (flag & kSCANF_LengthMask)
  924. {
  925. /* Match failure. */
  926. return nassigned;
  927. }
  928. if (c[1] == 'l')
  929. {
  930. flag |= kSCANF_LengthLongLongInt;
  931. c++;
  932. }
  933. else
  934. {
  935. flag |= kSCANF_LengthLongInt;
  936. }
  937. c++;
  938. break;
  939. #endif /* SCANF_ADVANCED_ENABLE */
  940. #if SCANF_FLOAT_ENABLE
  941. case 'L':
  942. if (flag & kSCANF_LengthMask)
  943. {
  944. /* Match failure. */
  945. return nassigned;
  946. }
  947. flag |= kSCANF_LengthLongLongDouble;
  948. c++;
  949. break;
  950. #endif /* SCANF_FLOAT_ENABLE */
  951. case '0':
  952. case '1':
  953. case '2':
  954. case '3':
  955. case '4':
  956. case '5':
  957. case '6':
  958. case '7':
  959. case '8':
  960. case '9':
  961. if (field_width)
  962. {
  963. /* Match failure. */
  964. return nassigned;
  965. }
  966. do
  967. {
  968. field_width = field_width * 10 + *c - '0';
  969. c++;
  970. } while ((*c >= '0') && (*c <= '9'));
  971. break;
  972. case 'd':
  973. base = 10;
  974. flag |= kSCANF_TypeSinged;
  975. flag |= kSCANF_DestInt;
  976. c++;
  977. break;
  978. case 'u':
  979. base = 10;
  980. flag |= kSCANF_DestInt;
  981. c++;
  982. break;
  983. case 'o':
  984. base = 8;
  985. flag |= kSCANF_DestInt;
  986. c++;
  987. break;
  988. case 'x':
  989. case 'X':
  990. base = 16;
  991. flag |= kSCANF_DestInt;
  992. c++;
  993. break;
  994. case 'i':
  995. base = 0;
  996. flag |= kSCANF_DestInt;
  997. c++;
  998. break;
  999. #if SCANF_FLOAT_ENABLE
  1000. case 'a':
  1001. case 'A':
  1002. case 'e':
  1003. case 'E':
  1004. case 'f':
  1005. case 'F':
  1006. case 'g':
  1007. case 'G':
  1008. flag |= kSCANF_DestFloat;
  1009. c++;
  1010. break;
  1011. #endif /* SCANF_FLOAT_ENABLE */
  1012. case 'c':
  1013. flag |= kSCANF_DestChar;
  1014. if (!field_width)
  1015. {
  1016. field_width = 1;
  1017. }
  1018. c++;
  1019. break;
  1020. case 's':
  1021. flag |= kSCANF_DestString;
  1022. c++;
  1023. break;
  1024. default:
  1025. return nassigned;
  1026. }
  1027. }
  1028. if (!(flag & kSCANF_DestMask))
  1029. {
  1030. /* Format strings are exhausted. */
  1031. return nassigned;
  1032. }
  1033. if (!field_width)
  1034. {
  1035. /* Large than length of a line. */
  1036. field_width = 99;
  1037. }
  1038. /* Matching strings in input streams and assign to argument. */
  1039. switch (flag & kSCANF_DestMask)
  1040. {
  1041. case kSCANF_DestChar:
  1042. s = (const char *)p;
  1043. buf = va_arg(args_ptr, char *);
  1044. while ((field_width--) && (*p))
  1045. {
  1046. if (!(flag & kSCANF_Suppress))
  1047. {
  1048. *buf++ = *p++;
  1049. }
  1050. else
  1051. {
  1052. p++;
  1053. }
  1054. n_decode++;
  1055. }
  1056. if ((!(flag & kSCANF_Suppress)) && (s != p))
  1057. {
  1058. nassigned++;
  1059. }
  1060. break;
  1061. case kSCANF_DestString:
  1062. n_decode += ScanIgnoreWhiteSpace(&p);
  1063. s = p;
  1064. buf = va_arg(args_ptr, char *);
  1065. while ((field_width--) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') &&
  1066. (*p != '\r') && (*p != '\v') && (*p != '\f'))
  1067. {
  1068. if (flag & kSCANF_Suppress)
  1069. {
  1070. p++;
  1071. }
  1072. else
  1073. {
  1074. *buf++ = *p++;
  1075. }
  1076. n_decode++;
  1077. }
  1078. if ((!(flag & kSCANF_Suppress)) && (s != p))
  1079. {
  1080. /* Add NULL to end of string. */
  1081. *buf = '\0';
  1082. nassigned++;
  1083. }
  1084. break;
  1085. case kSCANF_DestInt:
  1086. n_decode += ScanIgnoreWhiteSpace(&p);
  1087. s = p;
  1088. val = 0;
  1089. if ((base == 0) || (base == 16))
  1090. {
  1091. if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))
  1092. {
  1093. base = 16;
  1094. if (field_width >= 1)
  1095. {
  1096. p += 2;
  1097. n_decode += 2;
  1098. field_width -= 2;
  1099. }
  1100. }
  1101. }
  1102. if (base == 0)
  1103. {
  1104. if (s[0] == '0')
  1105. {
  1106. base = 8;
  1107. }
  1108. else
  1109. {
  1110. base = 10;
  1111. }
  1112. }
  1113. neg = 1;
  1114. switch (*p)
  1115. {
  1116. case '-':
  1117. neg = -1;
  1118. n_decode++;
  1119. p++;
  1120. field_width--;
  1121. break;
  1122. case '+':
  1123. neg = 1;
  1124. n_decode++;
  1125. p++;
  1126. field_width--;
  1127. break;
  1128. default:
  1129. break;
  1130. }
  1131. while ((*p) && (field_width--))
  1132. {
  1133. if ((*p <= '9') && (*p >= '0'))
  1134. {
  1135. temp = *p - '0';
  1136. }
  1137. else if ((*p <= 'f') && (*p >= 'a'))
  1138. {
  1139. temp = *p - 'a' + 10;
  1140. }
  1141. else if ((*p <= 'F') && (*p >= 'A'))
  1142. {
  1143. temp = *p - 'A' + 10;
  1144. }
  1145. else
  1146. {
  1147. temp = base;
  1148. }
  1149. if (temp >= base)
  1150. {
  1151. break;
  1152. }
  1153. else
  1154. {
  1155. val = base * val + temp;
  1156. }
  1157. p++;
  1158. n_decode++;
  1159. }
  1160. val *= neg;
  1161. if (!(flag & kSCANF_Suppress))
  1162. {
  1163. #if SCANF_ADVANCED_ENABLE
  1164. switch (flag & kSCANF_LengthMask)
  1165. {
  1166. case kSCANF_LengthChar:
  1167. if (flag & kSCANF_TypeSinged)
  1168. {
  1169. *va_arg(args_ptr, signed char *) = (signed char)val;
  1170. }
  1171. else
  1172. {
  1173. *va_arg(args_ptr, unsigned char *) = (unsigned char)val;
  1174. }
  1175. break;
  1176. case kSCANF_LengthShortInt:
  1177. if (flag & kSCANF_TypeSinged)
  1178. {
  1179. *va_arg(args_ptr, signed short *) = (signed short)val;
  1180. }
  1181. else
  1182. {
  1183. *va_arg(args_ptr, unsigned short *) = (unsigned short)val;
  1184. }
  1185. break;
  1186. case kSCANF_LengthLongInt:
  1187. if (flag & kSCANF_TypeSinged)
  1188. {
  1189. *va_arg(args_ptr, signed long int *) = (signed long int)val;
  1190. }
  1191. else
  1192. {
  1193. *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val;
  1194. }
  1195. break;
  1196. case kSCANF_LengthLongLongInt:
  1197. if (flag & kSCANF_TypeSinged)
  1198. {
  1199. *va_arg(args_ptr, signed long long int *) = (signed long long int)val;
  1200. }
  1201. else
  1202. {
  1203. *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val;
  1204. }
  1205. break;
  1206. default:
  1207. /* The default type is the type int. */
  1208. if (flag & kSCANF_TypeSinged)
  1209. {
  1210. *va_arg(args_ptr, signed int *) = (signed int)val;
  1211. }
  1212. else
  1213. {
  1214. *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
  1215. }
  1216. break;
  1217. }
  1218. #else
  1219. /* The default type is the type int. */
  1220. if (flag & kSCANF_TypeSinged)
  1221. {
  1222. *va_arg(args_ptr, signed int *) = (signed int)val;
  1223. }
  1224. else
  1225. {
  1226. *va_arg(args_ptr, unsigned int *) = (unsigned int)val;
  1227. }
  1228. #endif /* SCANF_ADVANCED_ENABLE */
  1229. nassigned++;
  1230. }
  1231. break;
  1232. #if SCANF_FLOAT_ENABLE
  1233. case kSCANF_DestFloat:
  1234. n_decode += ScanIgnoreWhiteSpace(&p);
  1235. fnum = strtod(p, (char **)&s);
  1236. if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL))
  1237. {
  1238. break;
  1239. }
  1240. n_decode += (int)(s) - (int)(p);
  1241. p = s;
  1242. if (!(flag & kSCANF_Suppress))
  1243. {
  1244. if (flag & kSCANF_LengthLongLongDouble)
  1245. {
  1246. *va_arg(args_ptr, double *) = fnum;
  1247. }
  1248. else
  1249. {
  1250. *va_arg(args_ptr, float *) = (float)fnum;
  1251. }
  1252. nassigned++;
  1253. }
  1254. break;
  1255. #endif /* SCANF_FLOAT_ENABLE */
  1256. default:
  1257. return nassigned;
  1258. }
  1259. }
  1260. }
  1261. return nassigned;
  1262. }