fsl_str.c 42 KB

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