RSeries astromech firmware
FormatString.h
Go to the documentation of this file.
1 #ifndef FormatString_h
2 #define FormatString_h
3 
4 #pragma once
5 
6 #define FL_LEFTADJUST 0x0001U
7 #define FL_SIGN 0x0002U
8 #define FL_ZEROPAD 0x0004U
9 #define FL_ALTERNATE 0x0008U
10 #define FL_SPACE 0x0010U
11 #define FL_SHORT 0x0020U
12 #define FL_LONG 0x0040U
13 #define FL_LONGDOUBLE 0x0080U
14 #define FL_POINTER 0x0100U
15 
16 #define MAX_WIDTH ((SHRT_MAX - 9) / 10)
17 
18 #ifndef DBL_DIG
19 #define DBL_DIG 15
20 #endif
21 #define BUFFER_LEN 1000
22 
23 #define PUTSTR(szPutStr, iPutLen) \
24  { \
25  if (iPutLen > 0) \
26  if (iOutFoo(pvOutData, (const char*)szPutStr, (size_t)iPutLen) < 0) \
27  return -1; \
28  iOutCount += iPutLen; \
29  }
30 
31 #define PAD(szPadStr, iPadLen) \
32  { \
33  if (iPadLen > 0) \
34  { \
35  iTmp = iPadLen; \
36  while (iTmp >= 32) \
37  { \
38  if (iOutFoo(pvOutData, (const char*)szPadStr, 32) < 0) \
39  return -1; \
40  iOutCount += 32; \
41  iTmp -= 32; \
42  } \
43  if (iTmp) \
44  { \
45  if (iOutFoo(pvOutData, (const char*)szPadStr, (size_t)iTmp) < 0) \
46  return -1; \
47  iOutCount += iTmp; \
48  } \
49  } \
50  }
51 
52 #define PADSPACES(iPadWidth) PAD(szSpaces, iPadWidth)
53 #define PADZEROS(iPadWidth) PAD(szZeros, iPadWidth)
54 
55 static const char szSpaces[] = " ";
56 static const char szZeros[] = "00000000000000000000000000000000";
57 
59 struct SSnprintf
60 {
61  char* cpBuf;
62  size_t tRoomFor;
63  char* cpBuffer;
64  size_t tBufSize;
65  bool tGrow;
66 };
67 
68 #ifndef OUTFMT_NO_FLOAT
69 union UIEEE_754
71 {
72  unsigned long aul[2];
73  double dVal;
74 };
75 
76 static const int iEndianChk = 1;
77 
78 #define iIsBigEndian() (*(char*)&iEndianChk == 0)
79 
80 #define iIsNanOrInf(puVal) \
81  (/*lint -save -e506 */ /* Constant boolean value */ \
82  sizeof((*puVal).dVal) == sizeof((*puVal).aul) \
83  ? /* We assume 64-bits double in IEEE 754 format */ \
84  iIsBigEndian() \
85  ? /* Big endian */ \
86  (((*puVal).aul[0] & 0x7ff00000UL) == 0x7ff00000UL) \
87  ? /* Inf or Nan */ \
88  (((*puVal).aul[0] & 0x000fffffUL) || (*puVal).aul[1]) \
89  ? /* Nan */ \
90  ((*puVal).aul[0] & 0x80000000UL) \
91  ? 1 /* -Nan */ \
92  : 2 /* Nan */ \
93  : /* Inf */ \
94  ((*puVal).aul[0] & 0x80000000UL) \
95  ? 3 /* -Inf */ \
96  : 4 /* Inf */ \
97  : 0 \
98  : /* Little endian */ \
99  (((*puVal).aul[1] & 0x7ff00000UL) == 0x7ff00000UL) \
100  ? /* Inf or Nan */ \
101  (((*puVal).aul[1] & 0x000fffffUL) || (*puVal).aul[0]) \
102  ? /* Nan */ \
103  ((*puVal).aul[1] & 0x80000000UL) \
104  ? 1 /* -Nan */ \
105  : 2 /* Nan */ \
106  : /* Inf */ \
107  ((*puVal).aul[1] & 0x80000000UL) \
108  ? 3 /* -Inf */ \
109  : 4 /* Inf */ \
110  : 0 \
111  : 0 /*lint -restore */ \
112  )
113 #endif
114 
116 static int _vsOutFmt(int (*iOutFoo)(void* pvOutData, const char*, size_t),
117  void* pvOutData,
118  const char* szFmt,
119  va_list tArg)
120 {
121  int iOutCount = 0;
122  while (*szFmt)
123  {
124  unsigned int uiFlags;
125  int iWidth, iPrec, iPrefixLen, iLeadingZeros, iTmp;
126  int iStrLen;
127  const char* szStr;
128  const char* szPrefix;
129  unsigned char aucBuffer[BUFFER_LEN];
130 
131  if (*szFmt != '%')
132  {
133  szStr = szFmt++;
134 
135  while (*szFmt != '\0' && *szFmt != '%')
136  ++szFmt;
137  iStrLen = (int)(szFmt - szStr);
138  PUTSTR(szStr, iStrLen);
139  if (*szFmt == '\0')
140  break;
141  }
142  szPrefix = "";
143  iStrLen = iPrefixLen = 0;
144  uiFlags = 0;
145  ++szFmt;
146  while ((*szFmt == '-') || (*szFmt == '+') || (*szFmt == '0') || (*szFmt == '#') || (*szFmt == ' '))
147  {
148  switch (*szFmt++)
149  {
150  case '-':
151  uiFlags |= FL_LEFTADJUST;
152  break;
153  case '+':
154  uiFlags |= FL_SIGN;
155  break;
156  case '0':
157  uiFlags |= FL_ZEROPAD;
158  break;
159  case '#':
160  uiFlags |= FL_ALTERNATE;
161  break;
162  case ' ':
163  uiFlags |= FL_SPACE;
164  break;
165  default:
166  break;
167  }
168  }
169 
170  /* Get width */
171  if (*szFmt == '*')
172  {
173  ++szFmt;
174  iWidth = va_arg(tArg, int);
175  if (iWidth < 0)
176  {
177  iWidth = -iWidth;
178  uiFlags |= FL_LEFTADJUST;
179  }
180  }
181  else
182  {
183  for (iWidth = 0; (*szFmt >= '0') && (*szFmt <= '9'); szFmt++)
184  {
185  if (iWidth < MAX_WIDTH)
186  iWidth = iWidth * 10 + (*szFmt - '0');
187  }
188  }
189 
190  /* Get precision */
191  if (*szFmt == '.')
192  {
193  if (*++szFmt == '*')
194  {
195  ++szFmt;
196  iPrec = va_arg(tArg, int);
197  if (iPrec < 0)
198  iPrec = 0;
199  }
200  else
201  {
202  for (iPrec = 0; (*szFmt >= '0') && (*szFmt <= '9'); szFmt++)
203  {
204  iPrec = iPrec * 10 + (*szFmt - '0');
205  }
206  }
207  }
208  else
209  iPrec = -1;
210 
211  /* Get size */
212  switch (*szFmt)
213  {
214  case 'h':
215  uiFlags |= FL_SHORT;
216  ++szFmt;
217  break;
218  case 'l':
219  uiFlags |= FL_LONG;
220  ++szFmt;
221  break;
222  case 'L':
223  uiFlags |= FL_LONGDOUBLE;
224  ++szFmt;
225  break;
226  default:
227  ;
228  }
229 
230  switch (*szFmt)
231  {
232  case 'p':
233  uiFlags |= FL_POINTER;
234  /* Default %p formatting to 0x%08X on 32-bit platforms and 0x%016X on 64-bit platforms */
235  uiFlags |= FL_ZEROPAD;
236  iWidth = sizeof(void*) * 2;
237  /*FALLTHROUGH*/
238  case 'x':
239  case 'X': /*lint !e616 */
240  case 'o':
241  case 'u':
242  case 'd':
243  case 'i':
244  {
245  unsigned long ulValue;
246  char* pcChar = (char*)&aucBuffer[(sizeof aucBuffer) - 1];
247 
248  *pcChar = '\0';
249  if (uiFlags & FL_POINTER)
250  ulValue = (unsigned long)va_arg(tArg, void*);
251  else if (uiFlags & FL_LONG)
252  ulValue = (unsigned long)va_arg(tArg, long);
253  else
254  ulValue = (unsigned long)va_arg(tArg, int);
255 
256  /* Don't print anything? */
257  if (iPrec == 0 && ulValue == 0)
258  {
259  szFmt++;
260  continue;
261  }
262 
263  if (*szFmt == 'd' || *szFmt == 'i')
264  {
265  if ((long)ulValue < 0)
266  {
267  ulValue = -(long)ulValue; /*lint !e732 */
268  szPrefix = "-";
269  iPrefixLen = 1;
270  }
271  else if (uiFlags & FL_SIGN)
272  {
273  szPrefix = "+";
274  iPrefixLen = 1;
275  }
276  else if (uiFlags & FL_SPACE)
277  {
278  szPrefix = " ";
279  iPrefixLen = 1;
280  }
281  do
282  {
283  int iChar = ulValue % 10U;
284  ulValue /= 10UL;
285  *--pcChar = (char)('0' + iChar);
286  iStrLen++;
287  } while (ulValue);
288  }
289  else
290  {
291  const unsigned uiRadix = (*szFmt == 'u')
292  ? 10U
293  : (*szFmt == 'o') ? 8U : 16U;
294  const char* acDigits = (*szFmt == 'X')
295  ? "0123456789ABCDEF"
296  : "0123456789abcdef";
297 
298  if (uiFlags & FL_SHORT)
299  ulValue &= USHRT_MAX;
300 
301  do
302  {
303  *--pcChar = acDigits[ulValue % uiRadix];
304  ulValue /= uiRadix;
305  iStrLen++;
306  } while (ulValue);
307  if ((uiFlags & FL_ALTERNATE) && *pcChar != '0')
308  {
309  if (*szFmt == 'o')
310  {
311  iStrLen++;
312  *--pcChar = '0';
313  }
314  else if (*szFmt == 'X')
315  {
316  szPrefix = "0X";
317  iPrefixLen = 2;
318  }
319  else if (*szFmt == 'x')
320  {
321  szPrefix = "0x";
322  iPrefixLen = 2;
323  }
324  }
325  }
326  szStr = pcChar;
327  }
328 
329  /* Calc number of leading zeros */
330  iLeadingZeros = iStrLen < iPrec ? iPrec - iStrLen : 0;
331 
332  if (iPrec < 0 && ((uiFlags & (FL_ZEROPAD | FL_LEFTADJUST)) == FL_ZEROPAD))
333  {
334  iTmp = iWidth - iPrefixLen - iLeadingZeros - iStrLen;
335  if (iTmp > 0)
336  iLeadingZeros += iTmp;
337  }
338 
339  iWidth -= iPrefixLen + iLeadingZeros + iStrLen;
340 
341  if (!(uiFlags & FL_LEFTADJUST))
342  PADSPACES(iWidth);
343  PUTSTR(szPrefix, iPrefixLen);
344  PADZEROS(iLeadingZeros);
345  PUTSTR(szStr, iStrLen);
346  if (uiFlags & FL_LEFTADJUST)
347  PADSPACES(iWidth);
348  ++szFmt;
349  continue;
350 
351  case 'f':
352  case 'e':
353  case 'E':
354  case 'g':
355  case 'G':
356  {
357 #ifdef OUTFMT_NO_FLOAT
358  szStr = "(no float support)";
359  goto OutStr;
360 #else
361 #if 0
362  double dValue = (uiFlags & FL_LONGDOUBLE)
363  ? (double)va_arg(tArg, long double)
364  : va_arg(tArg, double);
365 #else
366  /* long double support */
367  double dValue = va_arg(tArg, double);
368 #endif
369  int iDecZeros, iExpZeros, iDecPoint, iFracDigs;
370  int iTrailZeros, iExpLen, iExp, iSavedPrec;
371  char *szFrac, *szExp;
372  char cFmt = *szFmt;
373  static const char* szNanInf[] = { "-NaN", "NaN",
374  "-Inf", "Inf" };
375 
376  iDecZeros = iExpZeros = iFracDigs = 0;
377  iTrailZeros = iExpLen = iExp = 0;
378  iSavedPrec = iPrec;
379  szExp = (char*)"";
380 
381  iTmp = iIsNanOrInf((union UIEEE_754*)&dValue);
382  if (iTmp)
383  {
384  szStr = szNanInf[iTmp - 1];
385  goto OutStr;
386  }
387 
388  if (dValue < 0.0)
389  {
390  dValue = -dValue;
391  szPrefix = "-";
392  iPrefixLen = 1;
393  }
394  else if (uiFlags & FL_SIGN)
395  {
396  szPrefix = "+";
397  iPrefixLen = 1;
398  }
399  else if (uiFlags & FL_SPACE)
400  {
401  szPrefix = " ";
402  iPrefixLen = 1;
403  }
404 
405  if (dValue >= 10.0)
406  {
407  if (dValue >= 1e16)
408  {
409  while (dValue >= 1e64)
410  {
411  dValue /= 1e64;
412  iExp += 64;
413  }
414  while (dValue >= 1e32)
415  {
416  dValue /= 1e32;
417  iExp += 32;
418  }
419  while (dValue >= 1e16)
420  {
421  dValue /= 1e16;
422  iExp += 16;
423  }
424  }
425  while (dValue >= 1e08)
426  {
427  dValue /= 1e08;
428  iExp += 8;
429  }
430  while (dValue >= 1e04)
431  {
432  dValue /= 1e04;
433  iExp += 4;
434  }
435  while (dValue >= 1e01)
436  {
437  dValue /= 1e01;
438  iExp += 1;
439  }
440  }
441  else if (dValue < 1.0 && dValue > 0.0)
442  {
443  if (dValue < 1e-15)
444  {
445  while (dValue < 1e-63)
446  {
447  dValue *= 1e64;
448  iExp -= 64;
449  }
450  while (dValue < 1e-31)
451  {
452  dValue *= 1e32;
453  iExp -= 32;
454  }
455  while (dValue < 1e-15)
456  {
457  dValue *= 1e16;
458  iExp -= 16;
459  }
460  }
461  while (dValue < 1e-7)
462  {
463  dValue *= 1e8;
464  iExp -= 8;
465  }
466  while (dValue < 1e-3)
467  {
468  dValue *= 1e4;
469  iExp -= 4;
470  }
471  while (dValue < 1e-0)
472  {
473  dValue *= 1e1;
474  iExp -= 1;
475  }
476  if (dValue >= 10.0)
477  {
478  dValue /= 1e1;
479  iExp += 1;
480  }
481  }
482 
483  if (iPrec < 0)
484  iPrec = iSavedPrec = 6;
485 
486  if (cFmt == 'g' || cFmt == 'G')
487  {
488  if (iExp < -4 || iExp >= iPrec)
489  {
490  cFmt = (char)(cFmt == 'g' ? 'e' : 'E');
491  --iPrec;
492  }
493  else
494  {
495  cFmt = 'f';
496  if (iPrec == 0)
497  iPrec = 1;
498  if (iExp >= 0)
499  {
500  iPrec -= iExp + 1;
501  }
502  else
503  {
504  iPrec += -iExp - 1;
505  }
506  }
507  if (iPrec < 0)
508  iPrec = 0;
509  }
510  szStr = (char*)aucBuffer;
511  iStrLen = 0;
512  if (cFmt == 'e' || cFmt == 'E')
513  {
514  iTmp = (int)dValue;
515  aucBuffer[iStrLen++] = (unsigned char)(iTmp + '0');
516  dValue -= iTmp;
517  dValue *= 10.;
518  }
519  else if (iExp < 0)
520  {
521  aucBuffer[iStrLen++] = '0';
522  }
523  else
524  {
525  if (iExp > DBL_DIG + 1)
526  {
527  iExpZeros = iExp - (DBL_DIG + 1);
528  iExp = DBL_DIG + 1;
529  }
530 
531  do
532  {
533  iTmp = (int)dValue;
534  aucBuffer[iStrLen++] = (unsigned char)(iTmp + '0');
535  dValue -= iTmp;
536  dValue *= 10.;
537  } while (iExp--);
538  }
539 
540  szFrac = (char*)&aucBuffer[iStrLen];
541  if (cFmt == 'f')
542  {
543  while (iDecZeros < iPrec && iExp < -1)
544  {
545  ++iDecZeros;
546  ++iExp;
547  }
548  }
549 
550  if (!iExpZeros)
551  {
552  while (iFracDigs + iDecZeros < iPrec && iStrLen + iFracDigs < DBL_DIG + 1)
553  {
554  iTmp = (int)dValue;
555  szFrac[iFracDigs++] = (char)(iTmp + '0');
556  dValue -= iTmp;
557  dValue *= 10.;
558  if (cFmt == 'f')
559  --iExp;
560  }
561  if (!iFracDigs && iDecZeros)
562  {
563  szFrac[iFracDigs++] = (char)'0';
564  --iDecZeros;
565  --iExp;
566  }
567  if (dValue >= 5.0 && (iFracDigs || !iPrec))
568  {
569  iTmp = iStrLen + iFracDigs - 1;
570  while (aucBuffer[iTmp] == '9' && iTmp >= 0)
571  aucBuffer[iTmp--] = '0';
572  if (iTmp == 0 && iDecZeros)
573  {
574  for (iTmp = iStrLen + iFracDigs - 1;
575  iTmp > 0;
576  iTmp--)
577  {
578  aucBuffer[iTmp] = aucBuffer[iTmp - 1];
579  }
580  aucBuffer[1]++;
581  iDecZeros--;
582  }
583  else if (iTmp >= 0)
584  {
585  if (cFmt == 'f')
586  {
587  if (iPrec + 1 + iExp >= 0)
588  {
589  aucBuffer[iTmp]++;
590  }
591  }
592  else if (iPrec == 0 || iFracDigs == iPrec)
593  {
594  aucBuffer[iTmp]++;
595  }
596  }
597  else
598  {
599  /* iTmp == -1 */
600  aucBuffer[0] = '1';
601  aucBuffer[iStrLen + iFracDigs] = '0';
602  if (cFmt == 'f')
603  {
604  if (iStrLen >= iSavedPrec && (*szFmt == 'g' || *szFmt == 'G'))
605  {
606  cFmt = (char)(*szFmt == 'g' ? 'e' : 'E');
607  iExp = iStrLen;
608  iStrLen = 1;
609  }
610  else
611  iStrLen++;
612  }
613  else
614  iExp++;
615  }
616  }
617  }
618 
619  if (*szFmt == 'g' || *szFmt == 'G')
620  {
621  if (uiFlags & FL_ALTERNATE)
622  {
623  iDecPoint = 1;
624  }
625  else
626  {
627  iTmp = iStrLen + iFracDigs - 1;
628  while (aucBuffer[iTmp--] == '0' && iFracDigs > 0)
629  {
630  iFracDigs--;
631  }
632  if (!iFracDigs)
633  iDecZeros = 0;
634  iTrailZeros = 0;
635  iDecPoint = iFracDigs ? 1 : 0;
636  }
637  if (iExp == 0)
638  goto SkipExp;
639  }
640  else
641  {
642  iTrailZeros = iPrec - iFracDigs - iDecZeros;
643  if (iTrailZeros < 0)
644  iTrailZeros = 0;
645  iDecPoint = iPrec || (uiFlags & FL_ALTERNATE) ? 1 : 0;
646  }
647 
648  if (cFmt == 'e' || cFmt == 'E')
649  {
650  szExp = &szFrac[iFracDigs];
651  szExp[iExpLen++] = cFmt;
652  szExp[iExpLen++] = (char)((iExp < 0)
653  ? (iExp = -iExp),
654  '-'
655  : '+');
656 #ifndef OUTFMT_LONG_EXP
657  if (iExp >= 100)
658 #endif
659  {
660  szExp[iExpLen++] = (char)(iExp / 100 + '0');
661  iExp %= 100;
662  }
663  szExp[iExpLen++] = (char)(iExp / 10 + '0');
664  szExp[iExpLen++] = (char)(iExp % 10 + '0');
665  }
666 
667  SkipExp:
668 #ifdef OUTFMT_NO_MINUS_ZERO
669  if ((iPrefixLen == 1 && *szPrefix == '-') && (iStrLen == 1 && *szStr == '0') && ((iFracDigs == 1 && *szFrac == '0') || iFracDigs == 0))
670  {
671  if (uiFlags & FL_SIGN)
672  szPrefix = " ";
673  else
674  iPrefixLen = 0;
675  }
676 #endif
677  if ((uiFlags & FL_ZEROPAD) && !(uiFlags & FL_LEFTADJUST))
678  {
679  iLeadingZeros = iWidth - (iPrefixLen + iStrLen + iExpZeros + iDecPoint + iDecZeros + iFracDigs + iTrailZeros + iExpLen);
680  if (iLeadingZeros < 0)
681  iLeadingZeros = 0;
682  }
683  else
684  iLeadingZeros = 0;
685 
686  iWidth -= iPrefixLen + iLeadingZeros + iStrLen + iExpZeros + iDecPoint + iDecZeros + iFracDigs + iTrailZeros + iExpLen;
687 
688  if (!(uiFlags & FL_LEFTADJUST))
689  PADSPACES(iWidth);
690  PUTSTR(szPrefix, iPrefixLen);
691  PADZEROS(iLeadingZeros);
692  PUTSTR(szStr, iStrLen);
693  PADZEROS(iExpZeros);
694  PUTSTR(".", iDecPoint);
695  PADZEROS(iDecZeros);
696  PUTSTR(szFrac, iFracDigs);
697  PADZEROS(iTrailZeros);
698  PUTSTR(szExp, iExpLen);
699  if (uiFlags & FL_LEFTADJUST)
700  PADSPACES(iWidth);
701  ++szFmt;
702  continue;
703 #endif
704  }
705  case 'c':
706  aucBuffer[0] = (unsigned char)va_arg(tArg, int);
707  szStr = (char*)aucBuffer;
708  iStrLen = 1;
709  break;
710  case 'S':
711  {
712  String* str = va_arg(tArg, String*);
713  if (str == NULL)
714  {
715  szStr = "(null)";
716  }
717  else
718  {
719  szStr = str->c_str();
720  }
721  goto OutStr;
722  }
723  case 's':
724  szStr = va_arg(tArg, char*);
725  if (szStr == NULL)
726  szStr = "(null)";
727  OutStr:
728  iStrLen = 0;
729  while (szStr[iStrLen] != '\0')
730  iStrLen++;
731  if (iPrec >= 0 && iPrec < iStrLen)
732  iStrLen = iPrec;
733  break;
734  case '%':
735  szStr = "%";
736  iStrLen = 1;
737  break;
738  case 'n':
739  if (uiFlags & FL_SHORT)
740  *va_arg(tArg, short*) = (short)iOutCount;
741  else if (uiFlags & FL_LONG)
742  *va_arg(tArg, long*) = (long)iOutCount;
743  else
744  *va_arg(tArg, int*) = (int)iOutCount;
745  ++szFmt;
746  continue;
747  default:
748  aucBuffer[0] = (unsigned char)*szFmt;
749  szStr = (char*)aucBuffer;
750  iStrLen = 1;
751  break;
752  }
753 
754  iWidth -= iStrLen;
755  if (uiFlags & FL_LEFTADJUST)
756  {
757  PUTSTR(szStr, iStrLen);
758  PADSPACES(iWidth);
759  }
760  else
761  {
762  PADSPACES(iWidth);
763  PUTSTR(szStr, iStrLen);
764  }
765  ++szFmt;
766  }
767  if (iOutFoo(pvOutData, NULL, 0) < 0)
768  return -1;
769  return iOutCount;
770 } /* _vsOutFmt */
771 
772 static bool sFormatString_init;
773 static bool sFormatString_PSRam;
774 
775 static int
776 snprintfOut(void* ps, const char* szStr, size_t tLen)
777 {
778  SSnprintf* psSnprintf = (SSnprintf*)ps;
779 
780  if (szStr == NULL && tLen == 0)
781  {
782  if (psSnprintf->tRoomFor)
783  {
784  *psSnprintf->cpBuf = '\0';
785  return 0;
786  }
787  return -1;
788  }
789  else
790  {
791  if (psSnprintf->tGrow && psSnprintf->tRoomFor <= tLen)
792  {
793  size_t growsize = (tLen - psSnprintf->tRoomFor) + 64;
794  psSnprintf->tBufSize += growsize;
795  size_t usedsize = psSnprintf->cpBuf - psSnprintf->cpBuffer;
796  psSnprintf->cpBuffer = (sFormatString_PSRam) ?
797  (char*)ps_realloc(psSnprintf->cpBuffer, psSnprintf->tBufSize) :
798  (char*)realloc(psSnprintf->cpBuffer, psSnprintf->tBufSize);
799  psSnprintf->cpBuf = psSnprintf->cpBuffer + usedsize;
800  psSnprintf->tRoomFor += growsize;
801  }
802  while (psSnprintf->tRoomFor > 1 && tLen > 0)
803  {
804  psSnprintf->tRoomFor--;
805  tLen--;
806  *psSnprintf->cpBuf++ = *szStr++;
807  }
808  if (tLen > 0)
809  {
810  *psSnprintf->cpBuf = '\0';
811  return -1;
812  }
813  return 0;
814  }
815 }
816 
817 int FormatString(char** acBuf, const char* szFmt, va_list tArg)
818 {
819  int iOutCnt;
820  SSnprintf ssnprintf;
821 
822  ssnprintf.tBufSize = 64;
823  if (!sFormatString_init)
824  {
825  sFormatString_PSRam = psramInit();
826  sFormatString_init = true;
827  }
828  ssnprintf.cpBuf = ssnprintf.cpBuffer = (sFormatString_PSRam) ?
829  (char*)ps_malloc(ssnprintf.tBufSize) : (char*)malloc(ssnprintf.tBufSize);
830  ssnprintf.tRoomFor = ssnprintf.tBufSize;
831  ssnprintf.tGrow = true;
832 
833  iOutCnt = _vsOutFmt(snprintfOut, (void*)&ssnprintf, szFmt, tArg);
834  *acBuf = ssnprintf.cpBuffer;
835 
836  return iOutCnt;
837 }
838 #endif
FL_SIGN
#define FL_SIGN
Definition: FormatString.h:7
FL_POINTER
#define FL_POINTER
Definition: FormatString.h:14
MAX_WIDTH
#define MAX_WIDTH
Definition: FormatString.h:16
iIsNanOrInf
#define iIsNanOrInf(puVal)
Definition: FormatString.h:80
PUTSTR
#define PUTSTR(szPutStr, iPutLen)
Definition: FormatString.h:23
FL_ZEROPAD
#define FL_ZEROPAD
Definition: FormatString.h:8
FL_LEFTADJUST
#define FL_LEFTADJUST
Definition: FormatString.h:6
PADZEROS
#define PADZEROS(iPadWidth)
Definition: FormatString.h:53
FL_LONG
#define FL_LONG
Definition: FormatString.h:12
FL_SHORT
#define FL_SHORT
Definition: FormatString.h:11
FormatString
int FormatString(char **acBuf, const char *szFmt, va_list tArg)
Definition: FormatString.h:817
FL_ALTERNATE
#define FL_ALTERNATE
Definition: FormatString.h:9
PADSPACES
#define PADSPACES(iPadWidth)
Definition: FormatString.h:52
FL_LONGDOUBLE
#define FL_LONGDOUBLE
Definition: FormatString.h:13
FL_SPACE
#define FL_SPACE
Definition: FormatString.h:10
DBL_DIG
#define DBL_DIG
Definition: FormatString.h:19
BUFFER_LEN
#define BUFFER_LEN
Definition: FormatString.h:21