You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

output.inl 63 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
  17. #define OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
  18. #define SECUREC_NULL_STRING_SIZE 8
  19. #define SECUREC_STATE_TABLE_SIZE 337
  20. #define SECUREC_OFFSET_BITS_WORD 16
  21. #define SECUREC_OFFSET_BITS_DWORD 32
  22. #define SECUREC_OFFSET_DIV_OCTAL 3
  23. #define SECUREC_OFFSET_DIV_HEX 4
  24. #define SECUREC_RADIX_OCTAL 8
  25. #define SECUREC_RADIX_DECIMAL 10
  26. #define SECUREC_RADIX_HEX 16
  27. /* Use two displacements to eliminate compilation warnings */
  28. #define SECUREC_SHR_DWORD(x) (((x) >> 16) >> 16)
  29. #define SECUREC_PREFIX_LEN 2
  30. /* size include '+' and '\0' */
  31. #define SECUREC_FLOAT_BUF_EXT 2
  32. #ifdef SECUREC_STACK_SIZE_LESS_THAN_1K
  33. #define SECUREC_FMT_STR_LEN 8
  34. #else
  35. #define SECUREC_FMT_STR_LEN 16
  36. #endif
  37. typedef struct {
  38. unsigned int flags;
  39. int fldWidth;
  40. int precision;
  41. int bufferIsWide; /* flag for buffer contains wide chars ;0 is not wide char */
  42. int dynWidth; /* %* 1 width from variable parameter ;0 not */
  43. int dynPrecision; /* %.* 1 precision from variable parameter ;0 not */
  44. } SecFormatAttr;
  45. typedef union {
  46. char *str; /* not a null terminated string */
  47. #if SECUREC_HAVE_WCHART
  48. wchar_t *wStr;
  49. #endif
  50. } SecFormatBuf;
  51. typedef union {
  52. char str[SECUREC_BUFFER_SIZE + 1];
  53. #ifdef SECUREC_FOR_WCHAR
  54. wchar_t wStr[SECUREC_BUFFER_SIZE + 1];
  55. #endif
  56. } SecBuffer;
  57. #if SECUREC_ENABLE_SPRINTF_FLOAT
  58. /* call system sprintf to format float value */
  59. static int SecIndirectSprintf(char *strDest, const char *format, ...)
  60. {
  61. int ret; /* If initialization causes e838 */
  62. va_list argList;
  63. va_start(argList, format);
  64. SECUREC_MASK_MSVC_CRT_WARNING
  65. ret = vsprintf(strDest, format, argList);
  66. SECUREC_END_MASK_MSVC_CRT_WARNING
  67. va_end(argList);
  68. (void)argList; /* to clear e438 last value assigned not used , the compiler will optimize this code */
  69. return ret;
  70. }
  71. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  72. /* out put long double value to dest */
  73. static int SecFormatLongDboule(char *strDest,const SecFormatAttr *formatAttr, const char *fmt, long double ldValue)
  74. {
  75. int fldWidth = ((formatAttr->flags & SECUREC_FLAG_LEFT) ? (-(formatAttr->fldWidth)) : formatAttr->fldWidth);
  76. if (formatAttr->dynWidth && formatAttr->dynPrecision) {
  77. return SecIndirectSprintf(strDest, fmt, fldWidth, formatAttr->precision, ldValue);
  78. } else if (formatAttr->dynWidth) {
  79. return SecIndirectSprintf(strDest, fmt, fldWidth, ldValue);
  80. } else if (formatAttr->dynPrecision) {
  81. return SecIndirectSprintf(strDest, fmt, formatAttr->precision, ldValue);
  82. }
  83. return SecIndirectSprintf(strDest, fmt, ldValue);
  84. }
  85. #endif
  86. /* out put double value to dest */
  87. static int SecFormatDboule(char *strDest, const SecFormatAttr *formatAttr, const char *fmt, double dValue)
  88. {
  89. int fldWidth = ((formatAttr->flags & SECUREC_FLAG_LEFT) ? (-(formatAttr->fldWidth)) : formatAttr->fldWidth);
  90. if (formatAttr->dynWidth && formatAttr->dynPrecision) {
  91. return SecIndirectSprintf(strDest, fmt, fldWidth, formatAttr->precision, dValue);
  92. } else if (formatAttr->dynWidth) {
  93. return SecIndirectSprintf(strDest, fmt, fldWidth, dValue);
  94. } else if (formatAttr->dynPrecision) {
  95. return SecIndirectSprintf(strDest, fmt, formatAttr->precision, dValue);
  96. }
  97. return SecIndirectSprintf(strDest, fmt, dValue);
  98. }
  99. #endif
  100. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  101. /* to clear e506 warning */
  102. static int SecIsSameSize(size_t sizeA, size_t sizeB)
  103. {
  104. return sizeA == sizeB;
  105. }
  106. #endif
  107. #define SECUREC_SPECIAL_DWORD(val32, numBase) do { \
  108. --formatBuf.str; \
  109. *(formatBuf.str) = digits[(val32) % (numBase)]; \
  110. } while (((val32) /= (numBase)) != 0)
  111. #if defined(SECUREC_USE_SPECIAL_DIV64) || (defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS))
  112. /*
  113. * Fast divide by 10 algorithm.
  114. * Calculation divisor multiply 0xcccccccccccccccdULL, resultHi64 >> 3 as quotient
  115. */
  116. static void SecU64Div10(SecUnsignedInt64 divisor, SecUnsignedInt64 *quotient, SecUnsignedInt32 *remainder)
  117. {
  118. SecUnsignedInt64 mask = 0xffffffffULL; /* use 0xffffffffULL as 32 bit mask */
  119. SecUnsignedInt64 magicHi = 0xccccccccULL; /* fast divide 10 magic numbers high 32bit 0xccccccccULL */
  120. SecUnsignedInt64 magicLow = 0xcccccccdULL; /* fast divide 10 magic numbers low 32bit 0xcccccccdULL */
  121. SecUnsignedInt64 divisorHi = (SecUnsignedInt64)(SECUREC_SHR_DWORD(divisor)); /* hig 32 bit use */
  122. SecUnsignedInt64 divisorLow = (SecUnsignedInt64)(divisor & mask); /* low 32 bit mask */
  123. SecUnsignedInt64 factorHi = divisorHi * magicHi;
  124. SecUnsignedInt64 factorLow1 = divisorHi * magicLow;
  125. SecUnsignedInt64 factorLow2 = divisorLow * magicHi;
  126. SecUnsignedInt64 factorLow3 = divisorLow * magicLow;
  127. SecUnsignedInt64 carry = (factorLow1 & mask) + (factorLow2 & mask) + SECUREC_SHR_DWORD(factorLow3);
  128. SecUnsignedInt64 resultHi64 = factorHi + SECUREC_SHR_DWORD(factorLow1) + \
  129. SECUREC_SHR_DWORD(factorLow2) + SECUREC_SHR_DWORD(carry);
  130. *quotient = resultHi64 >> 3; /* fast divide 10 magic numbers 3 */
  131. *remainder = (SecUnsignedInt32)(divisor - ((*quotient) * 10)); /* quotient mul 10 */
  132. return;
  133. }
  134. #if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
  135. /*
  136. * Divide function for VXWORKS
  137. */
  138. static int SecU64Div32(SecUnsignedInt64 divisor, SecUnsignedInt32 radix,
  139. SecUnsignedInt64 *quotient, SecUnsignedInt32 *remainder)
  140. {
  141. switch (radix) {
  142. case SECUREC_RADIX_DECIMAL:
  143. SecU64Div10(divisor, quotient, remainder);
  144. break;
  145. case SECUREC_RADIX_HEX:
  146. *quotient = divisor >> SECUREC_OFFSET_DIV_HEX;
  147. *remainder = divisor & 0xfULL; /* mask one hex number by 0xfULL */
  148. break;
  149. case SECUREC_RADIX_OCTAL:
  150. *quotient = divisor >> SECUREC_OFFSET_DIV_OCTAL;
  151. *remainder = divisor & 0x7ULL; /* mask one hex number by 0x7ULL */
  152. break;
  153. default:
  154. return -1;
  155. }
  156. return 0;
  157. }
  158. #endif
  159. #endif
  160. #if defined(SECUREC_USE_SPECIAL_DIV64)
  161. /* The compiler does not provide 64 bit division problems */
  162. #define SECUREC_SPECIAL_QWORD_BASE10(val64) do { \
  163. SecUnsignedInt64 quotient = 0; \
  164. SecUnsignedInt32 digit = 0; \
  165. SecU64Div10((val64), &(quotient), &(digit)); \
  166. --formatBuf.str; \
  167. *(formatBuf.str) = digits[digit]; \
  168. (val64) = quotient; \
  169. } while ((val64) != 0)
  170. #else
  171. #define SECUREC_SPECIAL_QWORD_BASE10(val64) do { \
  172. --formatBuf.str; \
  173. *(formatBuf.str) = digits[(val64) % SECUREC_RADIX_DECIMAL]; \
  174. } while (((val64) /= SECUREC_RADIX_DECIMAL) != 0)
  175. #endif
  176. #define SECUREC_SPECIAL_QWORD(val64, numBase) do { \
  177. --formatBuf.str; \
  178. *(formatBuf.str) = digits[(val64) % (numBase)]; \
  179. } while (((val64) /= (numBase)) != 0)
  180. #define SECUREC_SAFE_WRITE_STR_OPT(src, txtLen, outStream, outChars) do { \
  181. int ii_; \
  182. for (ii_ = 0; ii_ < (txtLen); ++ii_) { \
  183. *((SecChar *)(void *)((outStream)->cur)) = *(SecChar *)(src); \
  184. (outStream)->cur += sizeof(SecChar); \
  185. (src) = (src) + 1; \
  186. } \
  187. (outStream)->count -= (txtLen) * (int)(sizeof(SecChar)); \
  188. *(outChars) = *(outChars) + (txtLen); \
  189. } SECUREC_WHILE_ZERO
  190. #define SECUREC_SAFE_WRITE_STR(src, txtLen, outStream, outChars) do { \
  191. if ((txtLen) < 12) { /* performance optimization for mobile number length 12 */ \
  192. SECUREC_SAFE_WRITE_STR_OPT((src), (txtLen), (outStream), (outChars)); \
  193. } else { \
  194. SecDoMemcpy((outStream)->cur, (src), ((size_t)(unsigned int)(txtLen) * (sizeof(SecChar)))); \
  195. (outStream)->cur += (size_t)((size_t)(unsigned int)(txtLen) * (sizeof(SecChar))); \
  196. (outStream)->count -= (txtLen) * (int)(sizeof(SecChar)); \
  197. *(outChars) = *(outChars) + (txtLen); \
  198. } \
  199. } SECUREC_WHILE_ZERO
  200. #define SECUREC_SAFE_WRITE_CHAR(c, outStream, outChars) do { \
  201. *((SecChar *)(void *)((outStream)->cur)) = (SecChar)(c); \
  202. (outStream)->cur += sizeof(SecChar); \
  203. (outStream)->count -= (int)(sizeof(SecChar)); \
  204. *(outChars) = *(outChars) + 1; \
  205. } SECUREC_WHILE_ZERO
  206. #define SECUREC_SAFE_PADDING(padChar, padLen, outStream, outChars) do { \
  207. int ii_; \
  208. for (ii_ = 0; ii_ < (padLen); ++ii_) { \
  209. *((SecChar *)(void *)((outStream)->cur)) = (SecChar)(padChar); \
  210. (outStream)->cur += sizeof(SecChar); \
  211. } \
  212. (outStream)->count -= (padLen) * (int)(sizeof(SecChar)); \
  213. *(outChars) = *(outChars) + (padLen); \
  214. } SECUREC_WHILE_ZERO
  215. /* The count variable can be reduced to 0, and the external function complements the \0 terminator. */
  216. #define SECUREC_IS_REST_BUF_ENOUGH(stream, needLen) ((int)((stream)->count - \
  217. (int)(needLen) * (int)(sizeof(SecChar))) >= 0)
  218. #define SECUREC_FMT_STATE_OFFSET 256
  219. #ifdef SECUREC_FOR_WCHAR
  220. #define SECUREC_FMT_TYPE(c, fmtTable) ((((unsigned int)(int)(c)) <= (unsigned int)(int)SECUREC_CHAR('~')) ? \
  221. ((fmtTable)[(unsigned char)(c)]) : 0)
  222. #define SECUREC_DECODE_STATE(c, fmtTable, lastState) (SecFmtState)((((fmtTable)[(SECUREC_FMT_TYPE(c, (fmtTable))) * \
  223. ((unsigned char)STAT_INVALID + 1) + \
  224. (unsigned char)(lastState) + \
  225. SECUREC_FMT_STATE_OFFSET])))
  226. #else
  227. #define SECUREC_DECODE_STATE(c, fmtTable, lastState) (SecFmtState)(((fmtTable)[((fmtTable)[(unsigned char)(c)]) * \
  228. ((unsigned char)STAT_INVALID + 1) + \
  229. (unsigned char)(lastState) + \
  230. SECUREC_FMT_STATE_OFFSET]))
  231. #endif
  232. static void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)
  233. {
  234. switch (ch) {
  235. case SECUREC_CHAR(' '):
  236. attr->flags |= SECUREC_FLAG_SIGN_SPACE;
  237. break;
  238. case SECUREC_CHAR('+'):
  239. attr->flags |= SECUREC_FLAG_SIGN;
  240. break;
  241. case SECUREC_CHAR('-'):
  242. attr->flags |= SECUREC_FLAG_LEFT;
  243. break;
  244. case SECUREC_CHAR('0'):
  245. attr->flags |= SECUREC_FLAG_LEADZERO; /* add zero th the front */
  246. break;
  247. case SECUREC_CHAR('#'):
  248. attr->flags |= SECUREC_FLAG_ALTERNATE; /* output %x with 0x */
  249. break;
  250. default:
  251. break;
  252. }
  253. return;
  254. }
  255. /*
  256. * Decoded size identifier in format string to Reduce the number of lines of function code
  257. */
  258. static int SecDecodeSizeI(SecFormatAttr *attr, const SecChar **format)
  259. {
  260. #ifdef SECUREC_ON_64BITS
  261. attr->flags |= SECUREC_FLAG_I64; /* %I to INT64 */
  262. #endif
  263. if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) {
  264. (*format) += 2; /* add 2 to skip I64 */
  265. attr->flags |= SECUREC_FLAG_I64; /* %I64 to INT64 */
  266. } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) {
  267. (*format) += 2; /* add 2 to skip I32 */
  268. attr->flags &= ~SECUREC_FLAG_I64; /* %I64 to INT32 */
  269. } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) ||
  270. (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) ||
  271. (**format == SECUREC_CHAR('x')) || (**format == SECUREC_CHAR('X'))) {
  272. /* do nothing */
  273. } else {
  274. /* Compatibility code for "%I" just print I */
  275. return -1;
  276. }
  277. return 0;
  278. }
  279. /*
  280. * Decoded size identifier in format string
  281. */
  282. static int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format)
  283. {
  284. switch (ch) {
  285. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  286. case SECUREC_CHAR('j'):
  287. attr->flags |= SECUREC_FLAG_INTMAX;
  288. break;
  289. #endif
  290. case SECUREC_CHAR('q'):
  291. /* fall-through */ /* FALLTHRU */
  292. case SECUREC_CHAR('L'):
  293. attr->flags |= SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE;
  294. break;
  295. case SECUREC_CHAR('l'):
  296. if (**format == SECUREC_CHAR('l')) {
  297. *format = *format + 1;
  298. attr->flags |= SECUREC_FLAG_LONGLONG; /* long long */
  299. } else {
  300. attr->flags |= SECUREC_FLAG_LONG; /* long int or wchar_t */
  301. }
  302. break;
  303. case SECUREC_CHAR('t'):
  304. attr->flags |= SECUREC_FLAG_PTRDIFF;
  305. break;
  306. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  307. case SECUREC_CHAR('z'):
  308. /* fall-through */ /* FALLTHRU */
  309. case SECUREC_CHAR('Z'):
  310. attr->flags |= SECUREC_FLAG_SIZE;
  311. break;
  312. #endif
  313. case SECUREC_CHAR('I'):
  314. if (SecDecodeSizeI(attr, format) != 0) {
  315. /* Compatibility code for "%I" just print I */
  316. return -1;
  317. }
  318. break;
  319. case SECUREC_CHAR('h'):
  320. if (**format == SECUREC_CHAR('h')) {
  321. attr->flags |= SECUREC_FLAG_CHAR; /* char */
  322. } else {
  323. attr->flags |= SECUREC_FLAG_SHORT; /* short int */
  324. }
  325. break;
  326. case SECUREC_CHAR('w'):
  327. attr->flags |= SECUREC_FLAG_WIDECHAR; /* wide char */
  328. break;
  329. default:
  330. break;
  331. }
  332. return 0;
  333. }
  334. /*
  335. * Decoded char type identifier
  336. */
  337. static int SecDecodeTypeC(SecFormatAttr *attr, unsigned int cValue, SecFormatBuf *formatBuf, SecBuffer *buffer)
  338. {
  339. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS))
  340. attr->flags &= ~SECUREC_FLAG_LEADZERO;
  341. #endif
  342. #ifdef SECUREC_FOR_WCHAR
  343. attr->bufferIsWide = 1;
  344. if (attr->flags & SECUREC_FLAG_SHORT) {
  345. #if SECUREC_HAVE_MBTOWC
  346. /* multibyte character to wide character */
  347. char tmpChar[2]; /* One character string, length is 2 */
  348. tmpChar[0] = (char)(cValue & 0x00ff);
  349. tmpChar[1] = '\0';
  350. if (mbtowc(buffer->wStr, tmpChar, sizeof(tmpChar)) < 0) {
  351. return -1;
  352. }
  353. #else
  354. return -1;
  355. #endif
  356. } else {
  357. buffer->wStr[0] = (wchar_t)cValue;
  358. }
  359. formatBuf->wStr = buffer->wStr;
  360. return 1; /* only 1 wide character */
  361. #else /* SECUREC_FOR_WCHAR */
  362. attr->bufferIsWide = 0;
  363. if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
  364. #if SECUREC_HAVE_WCTOMB
  365. wchar_t wChar = (wchar_t)cValue;
  366. int textLen;
  367. /* wide character to multibyte character */
  368. SECUREC_MASK_MSVC_CRT_WARNING
  369. textLen = wctomb(buffer->str, wChar);
  370. SECUREC_END_MASK_MSVC_CRT_WARNING
  371. if (textLen < 0) {
  372. return -1;
  373. }
  374. formatBuf->str = buffer->str;
  375. return textLen;
  376. #else
  377. return -1;
  378. #endif
  379. } else {
  380. /* get multibyte character from argument */
  381. unsigned short temp;
  382. temp = (unsigned short)cValue;
  383. buffer->str[0] = (char)temp;
  384. formatBuf->str = buffer->str;
  385. return 1; /* only 1 character */
  386. }
  387. #endif
  388. }
  389. /* literal string to print null ptr, define it as array rather than const text area
  390. * is to avoid gcc warning with pointing const text with variable
  391. */
  392. #if SECUREC_HAVE_WCHART
  393. static wchar_t g_wStrNullString[SECUREC_NULL_STRING_SIZE] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' };
  394. #endif
  395. static char g_strNullString[SECUREC_NULL_STRING_SIZE] = "(null)";
  396. static int SecDecodeTypeSchar(const SecFormatAttr *attr, SecFormatBuf *formatBuf)
  397. {
  398. int finalPrecision = (attr->precision == -1) ? SECUREC_INT_MAX : attr->precision;
  399. int textLen;
  400. if (formatBuf->str == NULL) { /* NULL passed, use special string */
  401. formatBuf->str = g_strNullString;
  402. }
  403. if (finalPrecision == SECUREC_INT_MAX) {
  404. /* precision NOT assigned */
  405. /* The strlen performance is high when the string length is greater than 32 */
  406. textLen = (int)strlen(formatBuf->str);
  407. } else {
  408. /* precision assigned */
  409. size_t tmpLen;
  410. SECUREC_CALC_STR_LEN(formatBuf->str, (size_t)(unsigned int)finalPrecision, &tmpLen);
  411. textLen = (int)tmpLen;
  412. }
  413. return textLen;
  414. }
  415. #if SECUREC_HAVE_WCHART
  416. static int SecDecodeTypeSwchar(SecFormatAttr *attr, SecFormatBuf *formatBuf)
  417. {
  418. int finalPrecision = (attr->precision == -1) ? SECUREC_INT_MAX : attr->precision;
  419. int textLen;
  420. attr->bufferIsWide = 1;
  421. if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
  422. formatBuf->wStr = g_wStrNullString;
  423. }
  424. /* textLen in wchar_t */
  425. SECUREC_CALC_WSTR_LEN(formatBuf->wStr, finalPrecision, &textLen);
  426. return textLen;
  427. }
  428. #endif
  429. /*
  430. * Decoded string identifier
  431. */
  432. static int SecDecodeTypeS(SecFormatAttr *attr, char *argPtr, SecFormatBuf *formatBuf)
  433. {
  434. int textLen;
  435. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && (!defined(SECUREC_ON_UNIX))
  436. attr->flags &= ~SECUREC_FLAG_LEADZERO;
  437. #endif
  438. formatBuf->str = argPtr;
  439. #ifdef SECUREC_FOR_WCHAR
  440. #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
  441. if (!(attr->flags & SECUREC_FLAG_LONG)) {
  442. attr->flags |= SECUREC_FLAG_SHORT;
  443. }
  444. #endif
  445. if (attr->flags & SECUREC_FLAG_SHORT) {
  446. /* textLen now contains length in multibyte chars */
  447. textLen = SecDecodeTypeSchar(attr, formatBuf);
  448. } else {
  449. /* textLen now contains length in wide chars */
  450. textLen = SecDecodeTypeSwchar(attr, formatBuf);
  451. }
  452. #else /* SECUREC_FOR_WCHAR */
  453. if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
  454. /* textLen now contains length in wide chars */
  455. #if SECUREC_HAVE_WCHART
  456. textLen = SecDecodeTypeSwchar(attr, formatBuf);
  457. #else
  458. textLen = 0;
  459. #endif
  460. } else {
  461. /* textLen now contains length in multibyte chars */
  462. textLen = SecDecodeTypeSchar(attr, formatBuf);
  463. }
  464. #endif /* SECUREC_FOR_WCHAR */
  465. return textLen;
  466. }
  467. /*
  468. * Write one character to dest buffer
  469. */
  470. static void SecOutputOneChar(SecChar ch, SecPrintfStream *stream, int *counter)
  471. {
  472. /* normal state, write character */
  473. if (SECUREC_IS_REST_BUF_ENOUGH(stream, 1)) { /* only one char */
  474. SECUREC_SAFE_WRITE_CHAR(ch, stream, counter); /* char * cast to wchar * */
  475. } else {
  476. #ifdef SECUREC_FOR_WCHAR
  477. SecWriteCharW(ch, stream, counter);
  478. #else
  479. /* optimize function call to code */
  480. *counter = -1;
  481. stream->count = -1;
  482. #endif
  483. }
  484. }
  485. /*
  486. * Check precison in format
  487. */
  488. static int SecDecodePrecision(SecChar ch, SecFormatAttr *formatAttr)
  489. {
  490. if (formatAttr->dynPrecision == 0) {
  491. /* add digit to current precision */
  492. if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(formatAttr->precision)) {
  493. return -1;
  494. }
  495. formatAttr->precision = (int)SECUREC_MUL_TEN((unsigned int)formatAttr->precision) +
  496. (unsigned char)(ch - SECUREC_CHAR('0'));
  497. } else {
  498. if (formatAttr->precision < 0) {
  499. formatAttr->precision = -1;
  500. }
  501. if (formatAttr->precision > SECUREC_MAX_WIDTH_LEN) {
  502. return -1;
  503. }
  504. }
  505. return 0;
  506. }
  507. /*
  508. * Check width in format
  509. */
  510. static int SecDecodeWidth(SecChar ch, SecFormatAttr *formatAttr, SecFmtState lastState)
  511. {
  512. if (formatAttr->dynWidth == 0) {
  513. if (lastState != STAT_WIDTH) {
  514. formatAttr->fldWidth = 0;
  515. }
  516. if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(formatAttr->fldWidth)) {
  517. return -1;
  518. }
  519. formatAttr->fldWidth = (int)SECUREC_MUL_TEN((unsigned int)formatAttr->fldWidth) +
  520. (unsigned char)(ch - SECUREC_CHAR('0'));
  521. } else {
  522. if (formatAttr->fldWidth < 0) {
  523. formatAttr->flags |= SECUREC_FLAG_LEFT;
  524. formatAttr->fldWidth = (-formatAttr->fldWidth);
  525. if (formatAttr->fldWidth > SECUREC_MAX_WIDTH_LEN) {
  526. return -1;
  527. }
  528. }
  529. }
  530. return 0;
  531. }
  532. #ifdef SECUREC_FOR_WCHAR
  533. /*
  534. * Formatting output core functions for wchar version.Called by a function such as vswprintf_s
  535. * argList must not be declare as const
  536. */
  537. static int SecOutputSW(SecPrintfStream *stream, const wchar_t *cFormat, va_list argList)
  538. #else
  539. /*
  540. * Formatting output core functions for char version.Called by a function such as vsnprintf_s
  541. */
  542. static int SecOutputS(SecPrintfStream *stream, const char *cFormat, va_list argList)
  543. #endif
  544. {
  545. const SecChar *format = cFormat;
  546. #if SECUREC_ENABLE_SPRINTF_FLOAT
  547. char *floatBuf = NULL;
  548. #endif
  549. SecFormatBuf formatBuf;
  550. static const char *itoaUpperDigits = "0123456789ABCDEFX";
  551. static const char *itoaLowerDigits = "0123456789abcdefx";
  552. const char *digits = itoaUpperDigits;
  553. unsigned int radix = SECUREC_RADIX_DECIMAL;
  554. int charsOut; /* characters written */
  555. int prefixLen = 0; /* Must be initialized or compiler alerts */
  556. int padding = 0;
  557. int textLen; /* length of the text */
  558. int noOutput = 0; /* Must be initialized or compiler alerts */
  559. SecFmtState state;
  560. SecFmtState lastState;
  561. SecChar prefix[SECUREC_PREFIX_LEN] = { 0 };
  562. SecChar ch; /* currently read character */
  563. static const unsigned char stateTable[SECUREC_STATE_TABLE_SIZE] = {
  564. /* type 0: nospecial meanin;
  565. * 1: '%';
  566. * 2: '.'
  567. * 3: '*'
  568. * 4: '0'
  569. * 5: '1' ... '9'
  570. * 6: ' ', '+', '-', '#'
  571. * 7: 'h', 'l', 'L', 'F', 'w' , 'N','z','q','t','j'
  572. * 8: 'd','o','u','i','x','X','e','f','g'
  573. */
  574. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  575. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  576. 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00,
  577. 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  578. 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
  579. 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
  580. 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08,
  581. 0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
  582. /* fill zero for normal char 128 byte for 0x80 - 0xff */
  583. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  584. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  585. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  586. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  587. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  588. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  589. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  590. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  591. /* state 0: normal
  592. * 1: percent
  593. * 2: flag
  594. * 3: width
  595. * 4: dot
  596. * 5: precis
  597. * 6: size
  598. * 7: type
  599. * 8: invalid
  600. */
  601. 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
  602. 0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05,
  603. 0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,
  604. 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
  605. 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00,
  606. 0x00
  607. };
  608. SecFormatAttr formatAttr;
  609. SecBuffer buffer;
  610. formatAttr.flags = 0;
  611. formatAttr.bufferIsWide = 0; /* flag for buffer contains wide chars */
  612. formatAttr.fldWidth = 0;
  613. formatAttr.precision = 0;
  614. formatAttr.dynWidth = 0;
  615. formatAttr.dynPrecision = 0;
  616. charsOut = 0;
  617. textLen = 0;
  618. state = STAT_NORMAL; /* starting state */
  619. formatBuf.str = NULL;
  620. /* loop each format character */
  621. /* remove format != NULL */
  622. while ((ch = *format) != SECUREC_CHAR('\0') && charsOut >= 0) {
  623. ++format;
  624. lastState = state;
  625. state = SECUREC_DECODE_STATE(ch, stateTable, lastState);
  626. switch (state) {
  627. case STAT_NORMAL:
  628. SecOutputOneChar(ch, stream, &charsOut);
  629. continue;
  630. case STAT_PERCENT:
  631. /* set default values */
  632. prefixLen = 0;
  633. noOutput = 0;
  634. formatAttr.flags = 0;
  635. formatAttr.fldWidth = 0;
  636. formatAttr.precision = -1;
  637. formatAttr.bufferIsWide = 0;
  638. formatAttr.dynWidth = 0;
  639. formatAttr.dynPrecision = 0;
  640. break;
  641. case STAT_FLAG:
  642. /* set flag based on which flag character */
  643. SecDecodeFlags(ch, &formatAttr);
  644. break;
  645. case STAT_WIDTH:
  646. /* update width value */
  647. if (ch == SECUREC_CHAR('*')) {
  648. /* get width */
  649. formatAttr.fldWidth = (int)va_arg(argList, int);
  650. formatAttr.dynWidth = 1;
  651. } else {
  652. formatAttr.dynWidth = 0;
  653. }
  654. if (SecDecodeWidth(ch, &formatAttr, lastState) != 0) {
  655. return -1;
  656. }
  657. break;
  658. case STAT_DOT:
  659. formatAttr.precision = 0;
  660. break;
  661. case STAT_PRECIS:
  662. /* update precison value */
  663. if (ch == SECUREC_CHAR('*')) {
  664. /* get precision from arg list */
  665. formatAttr.precision = (int)va_arg(argList, int);
  666. formatAttr.dynPrecision = 1;
  667. } else {
  668. formatAttr.dynPrecision = 0;
  669. }
  670. if (SecDecodePrecision(ch, &formatAttr) != 0) {
  671. return -1;
  672. }
  673. break;
  674. case STAT_SIZE:
  675. /* read a size specifier, set the formatAttr.flags based on it */
  676. if (SecDecodeSize(ch, &formatAttr, &format) != 0) {
  677. /* Compatibility code for "%I" just print I */
  678. SecOutputOneChar(ch, stream, &charsOut);
  679. state = STAT_NORMAL;
  680. continue;
  681. }
  682. break;
  683. case STAT_TYPE:
  684. switch (ch) {
  685. case SECUREC_CHAR('C'):
  686. /* wide char */
  687. if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
  688. #ifdef SECUREC_FOR_WCHAR
  689. formatAttr.flags |= SECUREC_FLAG_SHORT;
  690. #else
  691. formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
  692. #endif
  693. }
  694. /* fall-through */
  695. /* FALLTHRU */
  696. case SECUREC_CHAR('c'):
  697. do {
  698. unsigned int cValue = (unsigned int)va_arg(argList, int);
  699. textLen = SecDecodeTypeC(&formatAttr, cValue, &formatBuf, &buffer);
  700. if (textLen < 0) {
  701. noOutput = 1;
  702. }
  703. } SECUREC_WHILE_ZERO;
  704. break;
  705. case SECUREC_CHAR('S'): /* wide char string */
  706. if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
  707. #ifndef SECUREC_FOR_WCHAR
  708. formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
  709. #else
  710. formatAttr.flags |= SECUREC_FLAG_SHORT;
  711. #endif
  712. }
  713. /* fall-through */
  714. /* FALLTHRU */
  715. case SECUREC_CHAR('s'):
  716. do {
  717. char *argPtr = (char *)va_arg(argList, char *);
  718. textLen = SecDecodeTypeS(&formatAttr, argPtr, &formatBuf);
  719. } SECUREC_WHILE_ZERO;
  720. break;
  721. case SECUREC_CHAR('n'):
  722. /* higher risk disable it */
  723. return -1;
  724. case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */
  725. case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */
  726. case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */
  727. case SECUREC_CHAR('A'): /* fall-through */ /* FALLTHRU */
  728. /* convert format char to lower , use Explicit conversion to clean up compilation warning */
  729. ch = (SecChar)(ch + ((SecChar)(SECUREC_CHAR('a')) - (SECUREC_CHAR('A'))));
  730. /* fall-through */
  731. /* FALLTHRU */
  732. case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */
  733. case SECUREC_CHAR('f'): /* fall-through */ /* FALLTHRU */
  734. case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */
  735. case SECUREC_CHAR('a'):
  736. #if SECUREC_ENABLE_SPRINTF_FLOAT
  737. do {
  738. int bufferSize = 0; /* size of formatBuf.str */
  739. /* floating point conversion */
  740. formatBuf.str = buffer.str; /* output buffer for float string with default size */
  741. /* compute the precision value */
  742. if (formatAttr.precision < 0) {
  743. formatAttr.precision = SECUREC_FLOAT_DEFAULT_PRECISION;
  744. } else if (formatAttr.precision == 0 && ch == SECUREC_CHAR('g')) {
  745. formatAttr.precision = 1;
  746. }
  747. /* calc buffer size to store double value
  748. * The maximum length of SECUREC_MAX_WIDTH_LEN is enough
  749. */
  750. if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
  751. if (formatAttr.precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE_LB)) {
  752. noOutput = 1;
  753. break;
  754. }
  755. /* Long double needs to meet the basic print length */
  756. bufferSize = SECUREC_FLOAT_BUFSIZE_LB + formatAttr.precision + SECUREC_FLOAT_BUF_EXT;
  757. } else {
  758. if (formatAttr.precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE)) {
  759. noOutput = 1;
  760. break;
  761. }
  762. /* Double needs to meet the basic print length */
  763. bufferSize = SECUREC_FLOAT_BUFSIZE + formatAttr.precision + SECUREC_FLOAT_BUF_EXT;
  764. }
  765. if (formatAttr.fldWidth > bufferSize) {
  766. bufferSize = formatAttr.fldWidth + SECUREC_FLOAT_BUF_EXT;
  767. }
  768. if (bufferSize > SECUREC_BUFFER_SIZE) {
  769. /* the current vlaue of SECUREC_BUFFER_SIZE could NOT store the
  770. * formatted float string
  771. */
  772. floatBuf = (char *)SECUREC_MALLOC(((size_t)(unsigned int)bufferSize));
  773. if (floatBuf != NULL) {
  774. formatBuf.str = floatBuf;
  775. } else {
  776. noOutput = 1;
  777. break;
  778. }
  779. }
  780. do {
  781. /* add following code to call system sprintf API for float number */
  782. const SecChar *pFloatFmt = format - 2; /* sub 2 to the position before 'f' or 'g' */
  783. int k;
  784. int fFmtStrLen;
  785. char fFmtBuf[SECUREC_FMT_STR_LEN];
  786. char *fFmtStr = fFmtBuf;
  787. char *fFmtHeap = NULL; /* to clear warning */
  788. while (SECUREC_CHAR('%') != *pFloatFmt) { /* must meet '%' */
  789. --pFloatFmt;
  790. }
  791. fFmtStrLen = (int)((format - pFloatFmt) + 1); /* with ending terminator */
  792. if (fFmtStrLen > SECUREC_FMT_STR_LEN) {
  793. /* if SECUREC_FMT_STR_LEN is NOT enough, alloc a new buffer */
  794. fFmtHeap = (char *)SECUREC_MALLOC((size_t)((unsigned int)fFmtStrLen));
  795. if (fFmtHeap == NULL) {
  796. noOutput = 1;
  797. break;
  798. } else {
  799. for (k = 0; k < fFmtStrLen - 1; ++k) {
  800. /* convert wchar to char */
  801. fFmtHeap[k] = (char)(pFloatFmt[k]); /* copy the format string */
  802. }
  803. fFmtHeap[k] = '\0';
  804. fFmtStr = fFmtHeap;
  805. }
  806. } else {
  807. /* purpose of the repeat code is to solve the tool alarm Redundant_Null_Check */
  808. for (k = 0; k < fFmtStrLen - 1; ++k) {
  809. /* convert wchar to char */
  810. fFmtBuf[k] = (char)(pFloatFmt[k]); /* copy the format string */
  811. }
  812. fFmtBuf[k] = '\0';
  813. }
  814. if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
  815. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  816. long double tmp = (long double)va_arg(argList, long double);
  817. textLen = SecFormatLongDboule(formatBuf.str, &formatAttr, fFmtStr, tmp);
  818. #else
  819. double tmp = (double)va_arg(argList, double);
  820. textLen = SecFormatDboule(formatBuf.str, &formatAttr, fFmtStr, tmp);
  821. #endif
  822. } else {
  823. double tmp = (double)va_arg(argList, double);
  824. textLen = SecFormatDboule(formatBuf.str, &formatAttr, fFmtStr, tmp);
  825. }
  826. if (fFmtHeap != NULL) {
  827. /* if buffer is alloced on heap, free it */
  828. SECUREC_FREE(fFmtHeap);
  829. fFmtHeap = NULL;
  830. /* to clear e438 last value assigned not used , the compiler will
  831. * optimize this code
  832. */
  833. (void)fFmtHeap;
  834. }
  835. if (textLen < 0 || textLen >= bufferSize) {
  836. /* bufferSize is large enough, just validation the return value */
  837. noOutput = 1;
  838. break;
  839. }
  840. /* no padding ,this variable to calculate amount of padding */
  841. formatAttr.fldWidth = textLen;
  842. prefixLen = 0; /* no padding ,this variable to calculate amount of padding */
  843. formatAttr.flags = 0; /* clear all internal formatAttr.flags */
  844. break;
  845. } SECUREC_WHILE_ZERO;
  846. } SECUREC_WHILE_ZERO;
  847. break;
  848. #else
  849. return -1;
  850. #endif
  851. case SECUREC_CHAR('p'): /* fall-through */ /* FALLTHRU */
  852. case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */
  853. case SECUREC_CHAR('x'):
  854. /* unsigned lower hex output */
  855. digits = itoaLowerDigits;
  856. radix = SECUREC_RADIX_HEX;
  857. switch (ch) {
  858. case SECUREC_CHAR('p'):
  859. /* print a pointer */
  860. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  861. formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
  862. #else
  863. formatAttr.flags |= SECUREC_FLAG_POINTER;
  864. #endif
  865. #ifdef SECUREC_ON_64BITS
  866. formatAttr.flags |= SECUREC_FLAG_I64; /* converting an int64 */
  867. #else
  868. formatAttr.flags |= SECUREC_FLAG_LONG; /* converting a long */
  869. #endif
  870. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX))
  871. #if defined(SECUREC_VXWORKS_PLATFORM)
  872. formatAttr.precision = 1;
  873. #else
  874. formatAttr.precision = 0;
  875. #endif
  876. formatAttr.flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */
  877. break;
  878. #else
  879. /* not linux vxwoks */
  880. #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
  881. formatAttr.precision = 1;
  882. #else
  883. formatAttr.precision = 2 * sizeof(void *); /* 2 precision of different systems */
  884. #endif
  885. #endif
  886. #if defined(SECUREC_ON_UNIX)
  887. break;
  888. #endif
  889. /* fall-through */ /* FALLTHRU */
  890. case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */
  891. /* unsigned upper hex output */
  892. digits = itoaUpperDigits;
  893. break;
  894. default:
  895. break;
  896. }
  897. if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
  898. /* alternate form means '0x' prefix */
  899. prefix[0] = SECUREC_CHAR('0');
  900. prefix[1] = (SecChar)(digits[16]); /* 16 for 'x' or 'X' */
  901. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))
  902. if (ch == 'p') {
  903. prefix[1] = SECUREC_CHAR('x');
  904. }
  905. #endif
  906. #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
  907. if (ch == 'p') {
  908. prefixLen = 0;
  909. } else {
  910. prefixLen = SECUREC_PREFIX_LEN;
  911. }
  912. #else
  913. prefixLen = SECUREC_PREFIX_LEN;
  914. #endif
  915. }
  916. /* fall-through */ /* FALLTHRU */
  917. case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
  918. case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
  919. case SECUREC_CHAR('u'): /* fall-through */ /* FALLTHRU */
  920. case SECUREC_CHAR('o'): /* fall-through */ /* FALLTHRU */
  921. switch (ch) {
  922. case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
  923. case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
  924. /* signed decimal output */
  925. formatAttr.flags |= SECUREC_FLAG_SIGNED;
  926. /* fall-through */ /* FALLTHRU */
  927. case SECUREC_CHAR('u'):
  928. radix = SECUREC_RADIX_DECIMAL;
  929. break;
  930. case SECUREC_CHAR('o'):
  931. /* unsigned octal output */
  932. radix = SECUREC_RADIX_OCTAL;
  933. if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
  934. /* alternate form means force a leading 0 */
  935. formatAttr.flags |= SECUREC_FLAG_FORCE_OCTAL;
  936. }
  937. break;
  938. default:
  939. break;
  940. }
  941. do {
  942. SecUnsignedInt64 number = 0; /* number to convert */
  943. SecInt64 l; /* temp long value */
  944. /* read argument into variable l */
  945. if (formatAttr.flags & SECUREC_FLAG_I64) {
  946. l = (SecInt64)va_arg(argList, SecInt64);
  947. } else if (formatAttr.flags & SECUREC_FLAG_LONGLONG) {
  948. l = (SecInt64)va_arg(argList, SecInt64);
  949. } else
  950. #ifdef SECUREC_ON_64BITS
  951. if (formatAttr.flags & SECUREC_FLAG_LONG) {
  952. l = (long)va_arg(argList, long);
  953. } else
  954. #endif /* SECUREC_ON_64BITS */
  955. if (formatAttr.flags & SECUREC_FLAG_CHAR) {
  956. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  957. l = (char)va_arg(argList, int); /* sign extend */
  958. if (l >= 128) { /* 128 on some platform, char is always unsigned */
  959. SecUnsignedInt64 tmpL = (SecUnsignedInt64)l;
  960. unsigned char tmpCh = (unsigned char)(~(tmpL));
  961. l = tmpCh + 1;
  962. formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
  963. }
  964. } else {
  965. l = (unsigned char)va_arg(argList, int); /* zero-extend */
  966. }
  967. } else if (formatAttr.flags & SECUREC_FLAG_SHORT) {
  968. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  969. l = (short)va_arg(argList, int); /* sign extend */
  970. } else {
  971. l = (unsigned short)va_arg(argList, int); /* zero-extend */
  972. }
  973. }
  974. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  975. else if (formatAttr.flags & SECUREC_FLAG_PTRDIFF) {
  976. l = (ptrdiff_t)va_arg(argList, ptrdiff_t); /* sign extend */
  977. } else if (formatAttr.flags & SECUREC_FLAG_SIZE) {
  978. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  979. /* No suitable macros were found to handle the branch */
  980. if (SecIsSameSize(sizeof(size_t), sizeof(long))) {
  981. l = va_arg(argList, long); /* sign extend */
  982. } else if (SecIsSameSize(sizeof(size_t), sizeof(long long))) {
  983. l = va_arg(argList, long long); /* sign extend */
  984. } else {
  985. l = va_arg(argList, int); /* sign extend */
  986. }
  987. } else {
  988. l = (SecInt64)(size_t)va_arg(argList, size_t); /* sign extend */
  989. }
  990. } else if (formatAttr.flags & SECUREC_FLAG_INTMAX) {
  991. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  992. l = va_arg(argList, SecInt64); /* sign extend */
  993. } else {
  994. /* sign extend */
  995. l = (SecInt64)(SecUnsignedInt64)va_arg(argList, SecUnsignedInt64);
  996. }
  997. }
  998. #endif
  999. else {
  1000. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  1001. l = va_arg(argList, int); /* sign extend */
  1002. } else {
  1003. l = (unsigned int)va_arg(argList, int); /* zero-extend */
  1004. }
  1005. }
  1006. /* check for negative; copy into number */
  1007. if ((formatAttr.flags & SECUREC_FLAG_SIGNED) && l < 0) {
  1008. number = (SecUnsignedInt64)(-l);
  1009. formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
  1010. } else {
  1011. number = (SecUnsignedInt64)l;
  1012. }
  1013. if (((formatAttr.flags & SECUREC_FLAG_I64) == 0) &&
  1014. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  1015. ((formatAttr.flags & SECUREC_FLAG_INTMAX) == 0) &&
  1016. #endif
  1017. #ifdef SECUREC_ON_64BITS
  1018. ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) == 0) &&
  1019. ((formatAttr.flags & SECUREC_FLAG_SIZE) == 0) &&
  1020. #if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */
  1021. ((formatAttr.flags & SECUREC_FLAG_LONG) == 0) &&
  1022. #endif
  1023. #endif
  1024. ((formatAttr.flags & SECUREC_FLAG_LONGLONG) == 0)) {
  1025. number &= 0xffffffff; /* use 0xffffffff as 32 bit mask */
  1026. }
  1027. /* check precision value for default */
  1028. if (formatAttr.precision < 0) {
  1029. formatAttr.precision = 1; /* default precision */
  1030. } else {
  1031. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  1032. formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
  1033. #else
  1034. if (!(formatAttr.flags & SECUREC_FLAG_POINTER)) {
  1035. formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
  1036. }
  1037. #endif
  1038. if (formatAttr.precision > SECUREC_MAX_PRECISION) {
  1039. formatAttr.precision = SECUREC_MAX_PRECISION;
  1040. }
  1041. }
  1042. /* Check if data is 0; if so, turn off hex prefix,
  1043. * 'p' add 0x prefix, otherwise not add prefix
  1044. */
  1045. if (number == 0) {
  1046. #if !(defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux))
  1047. prefixLen = 0;
  1048. #else
  1049. if ((ch == 'p') && (formatAttr.flags & SECUREC_FLAG_ALTERNATE)) {
  1050. prefixLen = SECUREC_PREFIX_LEN;
  1051. } else {
  1052. prefixLen = 0;
  1053. }
  1054. #endif
  1055. }
  1056. /* Convert data to ASCII */
  1057. formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE];
  1058. if (number > 0) {
  1059. #ifdef SECUREC_ON_64BITS
  1060. switch (radix) {
  1061. /* the compiler will optimize each one */
  1062. case SECUREC_RADIX_DECIMAL:
  1063. SECUREC_SPECIAL_QWORD_BASE10(number);
  1064. break;
  1065. case SECUREC_RADIX_HEX:
  1066. SECUREC_SPECIAL_QWORD(number, SECUREC_RADIX_HEX);
  1067. break;
  1068. case SECUREC_RADIX_OCTAL:
  1069. SECUREC_SPECIAL_QWORD(number, SECUREC_RADIX_OCTAL);
  1070. break;
  1071. default:
  1072. break;
  1073. }
  1074. #else /* for 32 bits system */
  1075. if (number <= 0xFFFFFFFFUL) {
  1076. /* in most case, the value to be converted is small value */
  1077. SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;
  1078. switch (radix) {
  1079. case SECUREC_RADIX_HEX:
  1080. SECUREC_SPECIAL_DWORD(n32Tmp, SECUREC_RADIX_HEX);
  1081. break;
  1082. case SECUREC_RADIX_OCTAL:
  1083. SECUREC_SPECIAL_DWORD(n32Tmp, SECUREC_RADIX_OCTAL);
  1084. break;
  1085. #ifdef _AIX
  1086. /* the compiler will optimize div 10 */
  1087. case SECUREC_RADIX_DECIMAL:
  1088. SECUREC_SPECIAL_DWORD(n32Tmp, SECUREC_RADIX_DECIMAL);
  1089. break;
  1090. #else
  1091. case SECUREC_RADIX_DECIMAL:
  1092. do {
  1093. /* fast div 10 */
  1094. SecUnsignedInt32 q;
  1095. SecUnsignedInt32 r;
  1096. do {
  1097. *--formatBuf.str = digits[n32Tmp % SECUREC_RADIX_DECIMAL];
  1098. q = (n32Tmp >> 1) + (n32Tmp >> 2); /* fast div magic 2 */
  1099. q = q + (q >> 4); /* fast div magic 4 */
  1100. q = q + (q >> 8); /* fast div magic 8 */
  1101. q = q + (q >> 16); /* fast div magic 16 */
  1102. q = q >> 3; /* fast div magic 3 */
  1103. r = n32Tmp - SECUREC_MUL_TEN(q);
  1104. n32Tmp = (r > 9) ? (q + 1) : q; /* fast div magic 9 */
  1105. } while (n32Tmp != 0);
  1106. } SECUREC_WHILE_ZERO;
  1107. break;
  1108. #endif
  1109. default:
  1110. break;
  1111. } /* end switch */
  1112. } else {
  1113. /* the value to be converted is greater than 4G */
  1114. #if defined(SECUREC_VXWORKS_VERSION_5_4)
  1115. do {
  1116. SecUnsignedInt32 digit = 0; /* ascii value of digit */
  1117. SecUnsignedInt64 quotient = 0;
  1118. if (SecU64Div32(number,(SecUnsignedInt32)radix, &quotient, &digit) != 0) {
  1119. noOutput = 1;
  1120. break;
  1121. }
  1122. *--formatBuf.str = digits[digit];
  1123. number = quotient;
  1124. } while (number != 0);
  1125. #else
  1126. switch (radix) {
  1127. /* the compiler will optimize div 10 */
  1128. case SECUREC_RADIX_DECIMAL:
  1129. SECUREC_SPECIAL_QWORD_BASE10(number);
  1130. break;
  1131. case SECUREC_RADIX_OCTAL:
  1132. SECUREC_SPECIAL_QWORD(number, SECUREC_RADIX_OCTAL);
  1133. break;
  1134. case SECUREC_RADIX_HEX:
  1135. SECUREC_SPECIAL_QWORD(number, SECUREC_RADIX_HEX);
  1136. break;
  1137. default:
  1138. break;
  1139. }
  1140. #endif
  1141. }
  1142. #endif
  1143. }
  1144. /* compute length of number,.if textLen > 0, then formatBuf.str must be in buffer.str */
  1145. textLen = (int)(size_t)((char *)&buffer.str[SECUREC_BUFFER_SIZE] - formatBuf.str);
  1146. if (formatAttr.precision > textLen) {
  1147. int ii;
  1148. for (ii = 0; ii < formatAttr.precision - textLen; ++ii) {
  1149. *--formatBuf.str = '0';
  1150. }
  1151. textLen = formatAttr.precision;
  1152. }
  1153. /* Force a leading zero if FORCEOCTAL flag set */
  1154. if ((formatAttr.flags & SECUREC_FLAG_FORCE_OCTAL) &&
  1155. (textLen == 0 || formatBuf.str[0] != '0')) {
  1156. *--formatBuf.str = '0';
  1157. ++textLen; /* add a zero */
  1158. }
  1159. } SECUREC_WHILE_ZERO;
  1160. break;
  1161. default:
  1162. break;
  1163. }
  1164. while (noOutput < 1) {
  1165. if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
  1166. if (formatAttr.flags & SECUREC_FLAG_NEGATIVE) {
  1167. /* prefix is a '-' */
  1168. prefix[0] = SECUREC_CHAR('-');
  1169. prefixLen = 1;
  1170. } else if (formatAttr.flags & SECUREC_FLAG_SIGN) {
  1171. /* prefix is '+' */
  1172. prefix[0] = SECUREC_CHAR('+');
  1173. prefixLen = 1;
  1174. } else if (formatAttr.flags & SECUREC_FLAG_SIGN_SPACE) {
  1175. /* prefix is ' ' */
  1176. prefix[0] = SECUREC_CHAR(' ');
  1177. prefixLen = 1;
  1178. }
  1179. }
  1180. #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))
  1181. if ((formatAttr.flags & SECUREC_FLAG_POINTER) && (textLen == 0)) {
  1182. formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
  1183. formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE - 1];
  1184. *formatBuf.str-- = '\0';
  1185. *formatBuf.str-- = ')';
  1186. *formatBuf.str-- = 'l';
  1187. *formatBuf.str-- = 'i';
  1188. *formatBuf.str-- = 'n';
  1189. *formatBuf.str = '(';
  1190. textLen = 5; /* length of (nil) is 5 */
  1191. }
  1192. #endif
  1193. /* calculate amount of padding */
  1194. padding = (formatAttr.fldWidth - textLen) - prefixLen;
  1195. /* put out the padding, prefix, and text, in the correct order */
  1196. if (!(formatAttr.flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) && padding > 0) {
  1197. /* pad on left with blanks */
  1198. if (SECUREC_IS_REST_BUF_ENOUGH(stream, padding)) {
  1199. /* char * cast to wchar * */
  1200. SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
  1201. } else {
  1202. SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
  1203. }
  1204. }
  1205. /* write prefix */
  1206. if (prefixLen > 0) {
  1207. SecChar *pPrefix = prefix;
  1208. if (SECUREC_IS_REST_BUF_ENOUGH(stream, prefixLen)) {
  1209. /* max prefix len is 2, use loop copy */ /* char * cast to wchar * in WCHAR version */
  1210. SECUREC_SAFE_WRITE_STR_OPT(pPrefix, prefixLen, stream, &charsOut);
  1211. } else {
  1212. SECUREC_WRITE_STRING(prefix, prefixLen, stream, &charsOut);
  1213. }
  1214. }
  1215. if ((formatAttr.flags & SECUREC_FLAG_LEADZERO) && !(formatAttr.flags & SECUREC_FLAG_LEFT)
  1216. && padding > 0) {
  1217. /* write leading zeros */
  1218. if (SECUREC_IS_REST_BUF_ENOUGH(stream, padding)) {
  1219. /* char * cast to wchar * */
  1220. SECUREC_SAFE_PADDING(SECUREC_CHAR('0'), padding, stream, &charsOut);
  1221. } else {
  1222. SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR('0'), padding, stream, &charsOut);
  1223. }
  1224. }
  1225. /* write text */
  1226. #ifndef SECUREC_FOR_WCHAR
  1227. if (formatAttr.bufferIsWide != 0 && (textLen > 0)) {
  1228. #if SECUREC_HAVE_WCTOMB
  1229. wchar_t *p = formatBuf.wStr;
  1230. int count = textLen;
  1231. while (count > 0) {
  1232. char tmpBuf[SECUREC_MB_LEN + 1];
  1233. SECUREC_MASK_MSVC_CRT_WARNING
  1234. int retVal = wctomb(tmpBuf, *p);
  1235. SECUREC_END_MASK_MSVC_CRT_WARNING
  1236. if (retVal <= 0) {
  1237. charsOut = -1;
  1238. break;
  1239. }
  1240. SECUREC_WRITE_STRING(tmpBuf, retVal, stream, &charsOut);
  1241. --count;
  1242. ++p;
  1243. }
  1244. #else
  1245. charsOut = -1;
  1246. break;
  1247. #endif
  1248. } else {
  1249. if (SECUREC_IS_REST_BUF_ENOUGH(stream, textLen)) {
  1250. SECUREC_SAFE_WRITE_STR(formatBuf.str, textLen, stream, &charsOut);
  1251. } else {
  1252. SECUREC_WRITE_STRING(formatBuf.str, textLen, stream, &charsOut);
  1253. }
  1254. }
  1255. #else /* SECUREC_FOR_WCHAR */
  1256. if (formatAttr.bufferIsWide == 0 && textLen > 0) {
  1257. #if SECUREC_HAVE_MBTOWC
  1258. int count = textLen;
  1259. char *p = formatBuf.str;
  1260. while (count > 0) {
  1261. wchar_t wChar = L'\0';
  1262. int retVal = mbtowc(&wChar, p, (size_t)MB_CUR_MAX);
  1263. if (retVal <= 0) {
  1264. charsOut = -1;
  1265. break;
  1266. }
  1267. SecWriteCharW(wChar, stream, &charsOut);
  1268. p += retVal;
  1269. count -= retVal;
  1270. }
  1271. #else
  1272. charsOut = -1;
  1273. break;
  1274. #endif
  1275. } else {
  1276. if (SECUREC_IS_REST_BUF_ENOUGH(stream, textLen)) {
  1277. /* char * cast to wchar * */
  1278. SECUREC_SAFE_WRITE_STR(formatBuf.wStr, textLen, stream, &charsOut);
  1279. } else {
  1280. SECUREC_WRITE_STRING(formatBuf.wStr, textLen, stream, &charsOut);
  1281. }
  1282. }
  1283. #endif /* SECUREC_FOR_WCHAR */
  1284. if (charsOut >= 0 && (formatAttr.flags & SECUREC_FLAG_LEFT) && padding > 0) {
  1285. /* pad on right with blanks */
  1286. if (SECUREC_IS_REST_BUF_ENOUGH(stream, padding)) {
  1287. /* char * cast to wchar * */
  1288. SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
  1289. } else {
  1290. SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
  1291. }
  1292. }
  1293. break;
  1294. }
  1295. #if SECUREC_ENABLE_SPRINTF_FLOAT
  1296. if (floatBuf != NULL) {
  1297. SECUREC_FREE(floatBuf);
  1298. floatBuf = NULL;
  1299. }
  1300. #endif
  1301. break;
  1302. case STAT_INVALID:
  1303. return -1;
  1304. default:
  1305. return -1; /* input format is wrong, directly return */
  1306. }
  1307. }
  1308. if (state != STAT_NORMAL && state != STAT_TYPE) {
  1309. return -1;
  1310. }
  1311. return charsOut; /* the number of characters written */
  1312. }
  1313. #endif /* OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */