• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "stdio.h"
17 #include <stdarg.h>
18 #include <securec.h>
19 #include "fcntl.h"
20 #include "unistd.h"
21 #include <log.h>
22 
23 #ifndef LOSCFG_BASE_CORE_HILOG
24 #include <stdatomic.h>
25 #include "hilog_trace.h"
26 #endif
27 
28 typedef int SecInt32;
29 typedef unsigned int SecUnsignedInt32;
30 typedef long long SecInt64;
31 typedef unsigned long long SecUnsignedInt64;
32 
33 #ifndef LOSCFG_BASE_CORE_HILOG
34 static RegisterFunc g_registerFunc = NULL;
35 static atomic_int g_hiLogGetIdCallCount = 0;
36 #endif
37 
38 #ifndef SECUREC_BUFFER_SIZE
39 #define SECUREC_BUFFER_SIZE 256
40 #endif
41 
42 #define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE
43 /* max. # bytes in multibyte char  ,see MB_LEN_MAX */
44 #define SECUREC_MB_LEN 16
45 
46 /* state definitions */
47 #define SECUREC_FLAG_SIGN 0x00001U
48 #define SECUREC_FLAG_SIGN_SPACE 0x00002U
49 #define SECUREC_FLAG_LEFT 0x00004U
50 #define SECUREC_FLAG_LEADZERO 0x00008U
51 #define SECUREC_FLAG_LONG 0x00010U
52 #define SECUREC_FLAG_SHORT 0x00020U
53 #define SECUREC_FLAG_SIGNED 0x00040U
54 #define SECUREC_FLAG_ALTERNATE 0x00080U
55 #define SECUREC_FLAG_NEGATIVE 0x00100U
56 #define SECUREC_FLAG_FORCE_OCTAL 0x00200U
57 #define SECUREC_FLAG_LONG_DOUBLE 0x00400U
58 #define SECUREC_FLAG_WIDECHAR 0x00800U
59 #define SECUREC_FLAG_LONGLONG 0x01000U
60 #define SECUREC_FLAG_CHAR 0x02000U
61 #define SECUREC_FLAG_POINTER 0x04000U
62 #define SECUREC_FLAG_I64 0x08000U
63 #define SECUREC_FLAG_PTRDIFF 0x10000U
64 #define SECUREC_FLAG_SIZE 0x20000U
65 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
66 #define SECUREC_FLAG_INTMAX 0x40000U
67 #endif
68 
69 
70 typedef enum {
71     STAT_NORMAL,
72     STAT_PERCENT,
73     STAT_FLAG,
74     STAT_WIDTH,
75     STAT_DOT,
76     STAT_PRECIS,
77     STAT_SIZE,
78     STAT_TYPE,
79     STAT_INVALID
80 } SecFmtState;
81 
82 #define SECUREC_PRINTF_TRUNCATE (-2)
83 typedef struct {
84     int count;
85     char *cur;
86 } SecPrintfStream;
87 #define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg)
88 #define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg)
89 #define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg)
90 
91 // Log type
92 #define LOG_BUF_SIZE (1024)
93 #define MAX_DOMAIN_TAG_SIZE 64
94 #define IOV_SIZE (3)
95 #define HILOG_IOV_SIZE 4
96 #define HITRACE_BUF_SIZE 128
97 #define MAX_INIT_RETRIES (500)
98 #define DOMAIN_MIN 0x0D000000
99 #define DOMAIN_MAX 0x0E000000
100 
101 #define SECUREC_FLOAT_BUFSIZE (309 + 40)     /* max float point value */
102 #define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* max long double value */
103 
104 #define SECUREC_INT_MAX 2147483647
105 
106 #define SECUREC_MUL10(x) ((((x) << 2) + (x)) << 1)
107 #define SECUREC_INT_MAX_DIV_TEN 21474836
108 #define SECUREC_MUL10_ADD_BEYOND_MAX(val) (((val) > SECUREC_INT_MAX_DIV_TEN))
109 
110 #ifdef SECUREC_STACK_SIZE_LESS_THAN_1K
111 #define SECUREC_FMT_STR_LEN (8)
112 #else
113 #define SECUREC_FMT_STR_LEN (16)
114 #endif
115 
116 #ifndef SECUREC_PUTC
117 #define SECUREC_PUTC(_c, _stream) ((--(_stream)->count >= 0) ? (*(_stream)->cur++ = (char)(_c)) : EOF)
118 #endif
119 /* to clear e835 */
120 #ifndef SECUREC_PUTC_ZERO
121 #define SECUREC_PUTC_ZERO(_stream) ((--(_stream)->count >= 0) ? ((*(_stream)->cur++ = (char)('\0'))) : EOF)
122 #endif
123 
124 #ifndef SECUREC_MALLOC
125 #define SECUREC_MALLOC(x) malloc((size_t)(x))
126 #endif
127 
128 #ifndef SECUREC_FREE
129 #define SECUREC_FREE(x) free((void *)(x))
130 #endif
131 
132 typedef char SecChar;
133 #define SECUREC_CHAR(x) x
134 /* put a char to output */
135 #define SECUREC_PUTC(_c, _stream) ((--(_stream)->count >= 0) ? (*(_stream)->cur++ = (char)(_c)) : EOF)
136 /* to clear e835 */
137 
138 #define SECUREC_PUTC_ZERO(_stream) ((--(_stream)->count >= 0) ? ((*(_stream)->cur++ = (char)('\0'))) : EOF)
139 
SecPutWcharStrEndingZero(SecPrintfStream * str,int zeroNum)140 int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroNum)
141 {
142     int succeed = 0;
143     int i;
144 
145     for (i = 0; i < zeroNum; ++i) {
146         if (SECUREC_PUTC_ZERO(str) == EOF) {
147             break;
148         }
149     }
150     if (i == zeroNum) {
151         succeed = 1;
152     }
153     return succeed;
154 }
155 
SecWriteMultiChar(char ch,int num,SecPrintfStream * f,int * pnumwritten)156 void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten)
157 {
158     int count = num;
159     while (count-- > 0) {
160         if (SECUREC_PUTC(ch, f) == EOF) {
161             *pnumwritten = -1;
162             break;
163         } else {
164             ++(*pnumwritten);
165         }
166     }
167 }
168 
SecWriteString(const char * string,int len,SecPrintfStream * f,int * pnumwritten)169 void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten)
170 {
171     const char *str = string;
172     int count = len;
173     while (count-- > 0) {
174         if (SECUREC_PUTC(*str, f) == EOF) {
175             *pnumwritten = -1;
176             break;
177         } else {
178             ++(*pnumwritten);
179             ++str;
180         }
181     }
182 }
183 
184 #ifndef LOSCFG_BASE_CORE_HILOG
HiLogRegisterGetIdFun(RegisterFunc registerFunc)185 int HiLogRegisterGetIdFun(RegisterFunc registerFunc)
186 {
187     if (g_registerFunc != NULL) {
188         return -1;
189     }
190     g_registerFunc = registerFunc;
191     return 0;
192 }
193 
HiLogUnregisterGetIdFun(RegisterFunc registerFunc)194 void HiLogUnregisterGetIdFun(RegisterFunc registerFunc)
195 {
196     if (g_registerFunc != registerFunc) {
197         return;
198     }
199 
200     g_registerFunc = NULL;
201     while (atomic_load(&g_hiLogGetIdCallCount) != 0) {
202         /* do nothing, just wait current callback return */
203     }
204 
205     return;
206 }
207 #endif
208 
209 #define SECUREC_WRITE_MULTI_CHAR SecWriteMultiChar
210 #define SECUREC_WRITE_STRING SecWriteString
211 
212 typedef struct {
213     unsigned int flags;
214     int fldWidth;
215     int precision;
216     int bufferIsWide; /* flag for buffer contains wide chars */
217     int dynWidth;     /* %*   1 width from variable parameter ;0 not */
218     int dynPrecision; /* %.*  1 precision from variable parameter ;0 not */
219 } SecFormatAttr;
220 
221 typedef union {
222     char *str; /* not a null terminated  string */
223     wchar_t *wStr;
224 } SecFormatBuf;
225 
226 typedef union {
227     char str[SECUREC_BUFFER_SIZE + 1];
228 #ifdef SECUREC_FOR_WCHAR
229     wchar_t wStr[SECUREC_BUFFER_SIZE + 1];
230 #endif
231 } SecBuffer;
232 
233 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
234 /* to clear e506 warning */
SecIsSameSize(size_t sizeA,size_t sizeB)235 static int SecIsSameSize(size_t sizeA, size_t sizeB)
236 {
237     return sizeA == sizeB;
238 }
239 #endif
240 #define SECUREC_WHILE_ZERO while (0)
241 
242 #define SECUREC_SPECIAL(_val, Base) case Base:                                      \
243         do {                                        \
244             *--formatBuf.str = digits[_val % Base]; \
245         } while ((_val /= Base) != 0)
246 
247 #define SECUREC_SAFE_WRITE_PREFIX(src, txtLen, _stream, outChars) \
248     do {                                                          \
249         for (ii = 0; ii < txtLen; ++ii) {                         \
250             *((SecChar *)(void *)(_stream->cur)) = *(src);        \
251             _stream->cur += sizeof(SecChar);                      \
252             ++(src);                                              \
253         }                                                         \
254         _stream->count -= txtLen * (int)(sizeof(SecChar));        \
255         *(outChars) = *(outChars) + (txtLen);                     \
256     }                                                             \
257     SECUREC_WHILE_ZERO
258 #define MOBILE_NUMBER_LENGTH 12
259 #define SECUREC_SAFE_WRITE_STR(src, txtLen, _stream, outChars)                                    \
260     do {                                                                                          \
261         if (txtLen < MOBILE_NUMBER_LENGTH) {                                                      \
262             for (ii = 0; ii < txtLen; ++ii) {                                                     \
263                 *((SecChar *)(void *)(_stream->cur)) = *(src);                                    \
264                 _stream->cur += sizeof(SecChar);                                                  \
265                 ++(src);                                                                          \
266             }                                                                                     \
267         } else {                                                                                  \
268             (void)memcpy_s(_stream->cur, ((size_t)(unsigned int)txtLen * (sizeof(SecChar))), src, \
269                 ((size_t)(unsigned int)txtLen * (sizeof(SecChar))));                              \
270             _stream->cur += (size_t)(unsigned int)txtLen * (sizeof(SecChar));                     \
271         }                                                                                         \
272         _stream->count -= txtLen * (int)(sizeof(SecChar));                                        \
273         *(outChars) = *(outChars) + (txtLen);                                                     \
274     }                                                                                             \
275     SECUREC_WHILE_ZERO
276 
277 #define SECUREC_SAFE_WRITE_CHAR(_ch, _stream, outChars) do {                                                     \
278         *((SecChar *)(void *)(_stream->cur)) = (SecChar)_ch; \
279         _stream->cur += sizeof(SecChar);                     \
280         _stream->count -= (int)(sizeof(SecChar));            \
281         *(outChars) = *(outChars) + 1;                       \
282     }                                                        \
283     SECUREC_WHILE_ZERO
284 
285 #define SECUREC_SAFE_PADDING(padChar, padLen, _stream, outChars)     \
286     do {                                                             \
287         for (ii = 0; ii < padLen; ++ii) {                            \
288             *((SecChar *)(void *)(_stream->cur)) = (SecChar)padChar; \
289             _stream->cur += sizeof(SecChar);                         \
290         }                                                            \
291         _stream->count -= padLen * (int)(sizeof(SecChar));           \
292         *(outChars) = *(outChars) + (padLen);                        \
293     }                                                                \
294     SECUREC_WHILE_ZERO
295 
296 /* The count variable can be reduced to 0, and the external function complements the \0 terminator. */
297 #define SECUREC_IS_REST_BUF_ENOUGH(needLen) ((int)(stream->count - (int)needLen * (int)(sizeof(SecChar))) >= 0)
298 
299 #define SECUREC_FMT_STATE_OFFSET 256
300 #ifdef SECUREC_FOR_WCHAR
301 #define SECUREC_FMT_TYPE(c, fmtTable) \
302     ((((unsigned int)(int)(c)) <= (unsigned int)(int)SECUREC_CHAR('~')) ? (fmtTable[(unsigned char)(c)]) : 0)
303 #define SECUREC_DECODE_STATE(c, fmtTable, laststate)                                               \
304     (SecFmtState)(((fmtTable[(SECUREC_FMT_TYPE(c, fmtTable)) * ((unsigned char)STAT_INVALID + 1) + \
305         (unsigned char)(laststate) + SECUREC_FMT_STATE_OFFSET])))
306 #else
307 #define SECUREC_DECODE_STATE(c, fmtTable, laststate)                                             \
308     (SecFmtState)((fmtTable[(fmtTable[(unsigned char)(c)]) * ((unsigned char)STAT_INVALID + 1) + \
309         (unsigned char)(laststate) + SECUREC_FMT_STATE_OFFSET]))
310 #endif
311 
SecDecodeFlags(SecChar ch,SecFormatAttr * attr)312 static void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)
313 {
314     switch (ch) {
315         case SECUREC_CHAR(' '):
316             attr->flags |= SECUREC_FLAG_SIGN_SPACE;
317             break;
318         case SECUREC_CHAR('+'):
319             attr->flags |= SECUREC_FLAG_SIGN;
320             break;
321         case SECUREC_CHAR('-'):
322             attr->flags |= SECUREC_FLAG_LEFT;
323             break;
324         case SECUREC_CHAR('0'):
325             attr->flags |= SECUREC_FLAG_LEADZERO; /* add zero th the front */
326             break;
327         case SECUREC_CHAR('#'):
328             attr->flags |= SECUREC_FLAG_ALTERNATE; /* output %x with 0x */
329             break;
330         default:
331             break;
332     }
333     return;
334 }
335 
SecDecodeSize(SecChar ch,SecFormatAttr * attr,const SecChar ** format)336 static int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format)
337 {
338     switch (ch) {
339 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
340         case SECUREC_CHAR('j'):
341             attr->flags |= SECUREC_FLAG_INTMAX;
342             break;
343 #endif
344         case SECUREC_CHAR('q'): /* fall-through */ /* FALLTHRU */
345         case SECUREC_CHAR('L'):
346             attr->flags |= SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE;
347             break;
348         case SECUREC_CHAR('l'):
349             if (**format == SECUREC_CHAR('l')) {
350                 ++(*format);
351                 attr->flags |= SECUREC_FLAG_LONGLONG; /* long long */
352             } else {
353                 attr->flags |= SECUREC_FLAG_LONG; /* long int or wchar_t */
354             }
355             break;
356         case SECUREC_CHAR('t'):
357             attr->flags |= SECUREC_FLAG_PTRDIFF;
358             break;
359 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
360         case SECUREC_CHAR('z'):
361             attr->flags |= SECUREC_FLAG_SIZE;
362             break;
363         case SECUREC_CHAR('Z'):
364             attr->flags |= SECUREC_FLAG_SIZE;
365             break;
366 #endif
367 
368         case SECUREC_CHAR('I'):
369 #ifdef SECUREC_ON_64BITS
370             attr->flags |= SECUREC_FLAG_I64; /* %I  to  INT64 */
371 #endif
372             if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) {
373                 (*format) += 2; /* Add 2 to skip I64 */
374                 attr->flags |= SECUREC_FLAG_I64; /* %I64  to  INT64 */
375             } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) {
376                 (*format) += 2; /* Add 2 to skip I32 */
377                 attr->flags &= ~SECUREC_FLAG_I64; /* %I64  to  INT32 */
378             } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) ||
379                 (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) || (**format == SECUREC_CHAR('x')) ||
380                 (**format == SECUREC_CHAR('X'))) {
381                 /* do nothing */
382             } else {
383                 /* Compatibility  code for "%I" just print I */
384                 return -1;
385             }
386             break;
387 
388         case SECUREC_CHAR('h'):
389             if (**format == SECUREC_CHAR('h'))
390                 attr->flags |= SECUREC_FLAG_CHAR; /* char */
391             else
392                 attr->flags |= SECUREC_FLAG_SHORT; /* short int */
393             break;
394 
395         case SECUREC_CHAR('w'):
396             attr->flags |= SECUREC_FLAG_WIDECHAR; /* wide char */
397             break;
398         default:
399             break;
400     }
401 
402     return 0;
403 }
404 
SecDecodeTypeC(SecFormatAttr * attr,unsigned int cValue,SecFormatBuf * formatBuf,SecBuffer * buffer)405 static int SecDecodeTypeC(SecFormatAttr *attr, unsigned int cValue, SecFormatBuf *formatBuf, SecBuffer *buffer)
406 {
407     int textLen;
408     wchar_t wchar;
409 
410 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS))
411     attr->flags &= ~SECUREC_FLAG_LEADZERO;
412 #endif
413 
414 #ifdef SECUREC_FOR_WCHAR
415     attr->bufferIsWide = 1;
416     wchar = (wchar_t)cValue;
417     if (attr->flags & SECUREC_FLAG_SHORT) {
418         /* multibyte character to wide  character */
419         char tempchar[2];
420         tempchar[0] = (char)(wchar & 0x00ff);
421         tempchar[1] = '\0';
422 
423         if (mbtowc(buffer->wStr, tempchar, sizeof(tempchar)) < 0) {
424             return -1;
425         }
426     } else {
427         buffer->wStr[0] = wchar;
428     }
429     formatBuf->wStr = buffer->wStr;
430     textLen = 1; /* only 1 wide character */
431 #else
432     attr->bufferIsWide = 0;
433     if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
434         wchar = (wchar_t)cValue;
435         /* wide  character  to multibyte character */
436         // SECUREC_MASK_MSVC_CRT_WARNING
437         textLen = wctomb(buffer->str, wchar);
438         // SECUREC_END_MASK_MSVC_CRT_WARNING
439         if (textLen < 0) {
440             return -1;
441         }
442     } else {
443         /* get  multibyte character from argument */
444         unsigned short temp;
445         temp = (unsigned short)cValue;
446         buffer->str[0] = (char)temp;
447         textLen = 1;
448     }
449     formatBuf->str = buffer->str;
450 #endif
451 
452     return textLen;
453 }
454 
SecDecodeTypeS(SecFormatAttr * attr,char * argPtr,SecFormatBuf * formatBuf)455 static int SecDecodeTypeS(SecFormatAttr *attr, char *argPtr, SecFormatBuf *formatBuf)
456 {
457     /* literal string to print null ptr, define it on stack rather than const text area
458        is to avoid gcc warning with pointing const text with variable */
459     static char strNullString[8] = "(null)";
460     static wchar_t wStrNullString[8] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' };
461 
462     int finalPrecision;
463     char *strEnd = NULL;
464     wchar_t *wStrEnd = NULL;
465     int textLen;
466 
467 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && (!defined(SECUREC_ON_UNIX))
468     attr->flags &= ~SECUREC_FLAG_LEADZERO;
469 #endif
470     finalPrecision = (attr->precision == -1) ? SECUREC_INT_MAX : attr->precision;
471     formatBuf->str = argPtr;
472 
473 #ifdef SECUREC_FOR_WCHAR
474 #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
475     if (!(attr->flags & SECUREC_FLAG_LONG)) {
476         attr->flags |= SECUREC_FLAG_SHORT;
477     }
478 #endif
479     if (attr->flags & SECUREC_FLAG_SHORT) {
480         if (formatBuf->str == NULL) { /* NULL passed, use special string */
481             formatBuf->str = strNullString;
482         }
483         strEnd = formatBuf->str;
484         for (textLen = 0; textLen < finalPrecision && *strEnd; textLen++) {
485             ++strEnd;
486         }
487         /* textLen now contains length in multibyte chars */
488     } else {
489         if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
490             formatBuf->wStr = wStrNullString;
491         }
492         attr->bufferIsWide = 1;
493         wStrEnd = formatBuf->wStr;
494         while (finalPrecision-- && *wStrEnd) {
495             ++wStrEnd;
496         }
497         textLen = (int)(wStrEnd - formatBuf->wStr); /* in wchar_ts */
498         /* textLen now contains length in wide chars */
499     }
500 #else /* SECUREC_FOR_WCHAR */
501     if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
502         if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
503             formatBuf->wStr = wStrNullString;
504         }
505         attr->bufferIsWide = 1;
506         wStrEnd = formatBuf->wStr;
507         while (finalPrecision-- && *wStrEnd) {
508             ++wStrEnd;
509         }
510         textLen = (int)(wStrEnd - formatBuf->wStr);
511     } else {
512         if (formatBuf->str == NULL) { /* meet NULL, use special string */
513             formatBuf->str = strNullString;
514         }
515 
516         if (finalPrecision == SECUREC_INT_MAX) {
517             /* precision NOT assigned */
518             /* The strlen performance is high when the string length is greater than 32 */
519             textLen = (int)strlen(formatBuf->str);
520         } else {
521             /* precision assigned */
522             strEnd = formatBuf->str;
523             while (finalPrecision-- && *strEnd) {
524                 ++strEnd;
525             }
526             textLen = (int)(strEnd - formatBuf->str); /* length of the string */
527         }
528     }
529 
530 #endif /* SECUREC_FOR_WCHAR */
531     return textLen;
532 }
533 
534 #define PUBLIC_FLAG_LEN (8)
535 #define PRIVATE_FLAG_LEN (9)
536 #define PUBLIC_FLAG "{public}"
537 #define PRIVATE_FLAG "{private}"
538 #define bool _Bool
539 static int HILOG_TRUE = 1;
540 static int HILOG_FALSE = 0;
541 
HiLogSecOutputS(SecPrintfStream * stream,bool isDebugMode,const char * cformat,va_list arglist)542 int HiLogSecOutputS(SecPrintfStream *stream, bool isDebugMode, const char *cformat, va_list arglist)
543 {
544     const SecChar *format = cformat;
545 
546     char *floatBuf = NULL;
547     SecFormatBuf formatBuf;
548     static const char *ITOA_UPPER_DIGITS = "0123456789ABCDEFX";
549     static const char *ITOA_LOWER_DIGITS = "0123456789abcdefx";
550     const char *digits = ITOA_UPPER_DIGITS;
551     int ii = 0;
552 
553     unsigned int radix;
554     int charsOut; /* characters written */
555 
556     int prefixLen = 0;
557     int padding = 0;
558 
559     int textLen;        /* length of the text */
560     int bufferSize = 0; /* size of formatBuf.str */
561     int noOutput = 0;
562 
563     SecFmtState state;
564     SecFmtState laststate;
565 
566     SecChar prefix[2] = { 0 };
567     SecChar ch; /* currently read character */
568     static char PRIVACY_STRING[] = "<private>";
569     static wchar_t WPRIVACY_STRING[] = { L'<', L'p', L'r', L'i', L'v', L'a', L't', L'e', L'>', L'\0'};
570     bool isPrivacy = HILOG_TRUE;
571 
572     static const unsigned char fmtCharTable[337] = {
573         /* type 0:    nospecial meanin;
574            1:   '%';
575            2:    '.'
576            3:    '*'
577            4:    '0'
578            5:    '1' ... '9'
579            6:    ' ', '+', '-', '#'
580            7:     'h', 'l', 'L', 'F', 'w' , 'N','z','q','t','j'
581            8:     'd','o','u','i','x','X','e','f','g'
582          */
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         0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00,
586         0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587         0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
588         0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
589         0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08,
590         0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
591         /* fill zero  for normal char 128 byte for 0x80 - 0xff */
592         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600         /* state  0: normal
601            1: percent
602            2: flag
603            3: width
604            4: dot
605            5: precis
606            6: size
607            7: type
608            8: invalid
609          */
610         0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
611         0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05,
612         0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,
613         0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
614         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00,
615         0x00
616     };
617 
618     SecFormatAttr formatAttr;
619     SecBuffer buffer;
620     formatAttr.flags = 0;
621     formatAttr.bufferIsWide = 0; /* flag for buffer contains wide chars */
622     formatAttr.fldWidth = 0;
623     formatAttr.precision = 0;
624     formatAttr.dynWidth = 0;
625     formatAttr.dynPrecision = 0;
626 
627     charsOut = 0;
628     textLen = 0;
629     state = STAT_NORMAL; /* starting state */
630     formatBuf.str = NULL;
631 
632     /* loop each format character */
633     /* remove format != NULL */
634     while ((ch = *format++) != SECUREC_CHAR('\0') && charsOut >= 0) {
635         laststate = state;
636         state = SECUREC_DECODE_STATE(ch, fmtCharTable, laststate);
637 
638         switch (state) {
639             case STAT_NORMAL:
640 
641             NORMAL_CHAR:
642 
643                 /* normal state, write character */
644                 if (SECUREC_IS_REST_BUF_ENOUGH(1 /* only one char */)) {
645                     SECUREC_SAFE_WRITE_CHAR(ch, stream, &charsOut); /* char * cast to wchar * */
646                 } else {
647 #ifdef SECUREC_FOR_WCHAR
648                     SECUREC_WRITE_CHAR(ch, stream, &charsOut);
649 #else
650                     /* optimize function call to code */
651                     charsOut = -1;
652                     stream->count = -1;
653 #endif
654                 }
655 
656                 continue;
657 
658             case STAT_PERCENT:
659                 /* set default values */
660                 prefixLen = 0;
661                 noOutput = 0;
662                 formatAttr.flags = 0;
663                 formatAttr.fldWidth = 0;
664                 formatAttr.precision = -1;
665                 formatAttr.bufferIsWide = 0;
666                 isPrivacy = HILOG_TRUE;
667                 if (0 == strncmp(format, PUBLIC_FLAG, PUBLIC_FLAG_LEN)) {
668                     isPrivacy = HILOG_FALSE;
669                     format += PUBLIC_FLAG_LEN;
670                     break;
671                 }
672                 if (0 == strncmp(format, PRIVATE_FLAG, PRIVATE_FLAG_LEN)) {
673                     isPrivacy = HILOG_TRUE;
674                     format += PRIVATE_FLAG_LEN;
675                     break;
676                 }
677 
678                 if (*format == SECUREC_CHAR('%')) {
679                     isPrivacy = HILOG_FALSE;
680                 }
681 
682                 break;
683 
684             case STAT_FLAG:
685                 /* set flag based on which flag character */
686                 SecDecodeFlags(ch, &formatAttr);
687                 break;
688 
689             case STAT_WIDTH:
690                 /* update width value */
691                 if (ch == SECUREC_CHAR('*')) {
692                     /* get width */
693                     formatAttr.fldWidth = (int)va_arg(arglist, int);
694                     if (formatAttr.fldWidth < 0) {
695                         formatAttr.flags |= SECUREC_FLAG_LEFT;
696                         formatAttr.fldWidth = -formatAttr.fldWidth;
697                     }
698                     formatAttr.dynWidth = 1;
699                 } else {
700                     if (laststate != STAT_WIDTH) {
701                         formatAttr.fldWidth = 0;
702                     }
703                     if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.fldWidth)) {
704                         return -1;
705                     }
706                     formatAttr.fldWidth =
707                         (int)SECUREC_MUL10((unsigned int)formatAttr.fldWidth) + (ch - SECUREC_CHAR('0'));
708                     formatAttr.dynWidth = 0;
709                 }
710                 break;
711 
712             case STAT_DOT:
713                 formatAttr.precision = 0;
714                 break;
715 
716             case STAT_PRECIS:
717                 /* update precison value */
718                 if (ch == SECUREC_CHAR('*')) {
719                     /* get precision from arg list */
720                     formatAttr.precision = (int)va_arg(arglist, int);
721                     if (formatAttr.precision < 0) {
722                         formatAttr.precision = -1;
723                     }
724                     formatAttr.dynPrecision = 1;
725                 } else {
726                     /* add digit to current precision */
727                     if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.precision)) {
728                         return -1;
729                     }
730                     formatAttr.precision =
731                         (int)SECUREC_MUL10((unsigned int)formatAttr.precision) + (ch - SECUREC_CHAR('0'));
732                     formatAttr.dynPrecision = 0;
733                 }
734                 break;
735 
736             case STAT_SIZE:
737                 /* read a size specifier, set the formatAttr.flags based on it */
738                 if (SecDecodeSize(ch, &formatAttr, &format) != 0) {
739                     /* Compatibility  code for "%I" just print I */
740                     state = STAT_NORMAL;
741                     goto NORMAL_CHAR;
742                 }
743                 break;
744 
745             case STAT_TYPE:
746 
747                 switch (ch) {
748                     case SECUREC_CHAR('C'):
749                         /* wide char */
750                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
751 #ifdef SECUREC_FOR_WCHAR
752                             formatAttr.flags |= SECUREC_FLAG_SHORT;
753 #else
754                             formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
755 #endif
756                         }
757                         /* fall-through */
758                         /* FALLTHRU */
759                     case SECUREC_CHAR('c'): {
760                         unsigned int cValue = (unsigned int)va_arg(arglist, int);
761                         textLen = SecDecodeTypeC(&formatAttr, cValue, &formatBuf, &buffer);
762                         if (textLen < 0) {
763                             noOutput = 1;
764                         }
765                     } break;
766                     case SECUREC_CHAR('S'): /* wide char string */
767 #ifndef SECUREC_FOR_WCHAR
768                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
769                             formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
770                         }
771 #else
772                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
773                             formatAttr.flags |= SECUREC_FLAG_SHORT;
774                         }
775 #endif
776                         /* fall-through */
777                         /* FALLTHRU */
778                     case SECUREC_CHAR('s'): {
779                         char *argPtr = (char *)va_arg(arglist, char *);
780                         textLen = SecDecodeTypeS(&formatAttr, argPtr, &formatBuf);
781                     } break;
782 
783                     case SECUREC_CHAR('n'):
784                         /* higher risk disable it */
785                         return -1;
786 
787                     case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */
788                     case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */
789                     case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */
790                     case SECUREC_CHAR('A'): /* fall-through */ /* FALLTHRU */
791                         /* convert format char to lower , use Explicit conversion to clean up compilation warning */
792                         ch = (SecChar)(ch + ((SecChar)(SECUREC_CHAR('a')) - (SECUREC_CHAR('A'))));
793                         /* fall-through */
794                         /* FALLTHRU */
795                     case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */
796                     case SECUREC_CHAR('f'): /* fall-through */ /* FALLTHRU */
797                     case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */
798                     case SECUREC_CHAR('a'): {
799                         /* floating point conversion */
800                         formatBuf.str = buffer.str; /* output buffer for float string with default size */
801 
802                         /* compute the precision value */
803                         if (formatAttr.precision < 0) {
804                             formatAttr.precision = 6; /* securec float default precision 6 */
805                         } else if (formatAttr.precision == 0 && ch == SECUREC_CHAR('g')) {
806                             formatAttr.precision = 1;
807                         }
808 
809                         /* calc buffer size to store long double value */
810                         if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
811                             if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE_LB)) {
812                                 noOutput = 1;
813                                 break;
814                             }
815                             bufferSize = SECUREC_FLOAT_BUFSIZE_LB + formatAttr.precision;
816                         } else {
817                             if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE)) {
818                                 noOutput = 1;
819                                 break;
820                             }
821                             bufferSize = SECUREC_FLOAT_BUFSIZE + formatAttr.precision;
822                         }
823                         if (formatAttr.fldWidth > bufferSize) {
824                             bufferSize = formatAttr.fldWidth;
825                         }
826 
827                         if (bufferSize >= SECUREC_BUFFER_SIZE) {
828                             /* the current vlaue of SECUREC_BUFFER_SIZE could NOT store the formatted float string */
829                             /* size include '+' and '\0' */
830                             floatBuf = (char *)SECUREC_MALLOC(((size_t)(unsigned int)bufferSize + (size_t)2));
831                             if (floatBuf != NULL) {
832                                 formatBuf.str = floatBuf;
833                             } else {
834                                 noOutput = 1;
835                                 break;
836                             }
837                         }
838 
839                         {
840                             /* add following code to call system sprintf API for float number */
841                             const SecChar *pFltFmt = format - 2; /* point to the position before 'f' or 'g' */
842                             int k = 0;
843                             int fltFmtStrLen;
844                             char fltFmtBuf[SECUREC_FMT_STR_LEN];
845                             char *fltFmtStr = fltFmtBuf;
846                             char *fltFmtHeap = NULL; /* to clear warning */
847 
848                             while (SECUREC_CHAR('%') != *pFltFmt && SECUREC_CHAR('}') != *pFltFmt) { /* must meet '%' */
849                                 --pFltFmt;
850                             }
851 
852                             fltFmtStrLen = (int)((format - pFltFmt) + 1); /* with ending terminator */
853                             if (fltFmtStrLen > SECUREC_FMT_STR_LEN) {
854                                 /* if SECUREC_FMT_STR_LEN is NOT enough, alloc a new buffer */
855                                 fltFmtHeap = (char *)SECUREC_MALLOC((size_t)((unsigned int)fltFmtStrLen));
856                                 if (fltFmtHeap == NULL) {
857                                     noOutput = 1;
858                                     break;
859                                 } else {
860                                     if (SECUREC_CHAR('%') != *pFltFmt) {
861                                         fltFmtHeap[0] = '%';
862                                         ++k;
863                                     }
864                                     for (; k < fltFmtStrLen - 1; ++k) {
865                                         /* convert wchar to char */
866                                         fltFmtHeap[k] = (char)(pFltFmt[k]); /* copy the format string */
867                                     }
868                                     fltFmtHeap[k] = '\0';
869 
870                                     fltFmtStr = fltFmtHeap;
871                                 }
872                             } else {
873                                 if (SECUREC_CHAR('%') != *pFltFmt) {
874                                     fltFmtBuf[0] = '%';
875                                     ++k;
876                                 }
877                                 /* purpose of the repeat code is to solve the tool alarm  Redundant_Null_Check */
878                                 for (; k < fltFmtStrLen - 1; ++k) {
879                                     /* convert wchar to char */
880                                     fltFmtBuf[k] = (char)(pFltFmt[k]); /* copy the format string */
881                                 }
882                                 fltFmtBuf[k] = '\0';
883                             }
884 
885 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
886                             if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
887                                 long double tmp = (long double)va_arg(arglist, long double);
888                                 /* call system sprintf to format float value */
889                                 if (formatAttr.dynWidth && formatAttr.dynPrecision) {
890                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
891                                         formatAttr.fldWidth, formatAttr.precision, tmp);
892                                 } else if (formatAttr.dynWidth) {
893                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
894                                         formatAttr.fldWidth, tmp);
895                                 } else if (formatAttr.dynPrecision) {
896                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
897                                         formatAttr.precision, tmp);
898                                 } else {
899                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr, tmp);
900                                 }
901                             } else
902 #endif
903                             {
904                                 double tmp = (double)va_arg(arglist, double);
905                                 if (formatAttr.dynWidth && formatAttr.dynPrecision) {
906                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
907                                         formatAttr.fldWidth, formatAttr.precision, tmp);
908                                 } else if (formatAttr.dynWidth) {
909                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
910                                         formatAttr.fldWidth, tmp);
911                                 } else if (formatAttr.dynPrecision) {
912                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
913                                         formatAttr.precision, tmp);
914                                 } else {
915                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr, tmp);
916                                 }
917                             }
918 
919                             if (fltFmtHeap != NULL) {
920                                 /* if buffer is alloced on heap, free it */
921                                 SECUREC_FREE(fltFmtHeap);
922                                 fltFmtHeap = NULL;
923                             }
924                             if (textLen < 0) {
925                                 /* bufferSize is large enough,just validation the return value */
926                                 noOutput = 1;
927                                 break;
928                             }
929 
930                             formatAttr.fldWidth =
931                                 textLen;          /* no padding ,this variable to calculate amount of padding */
932                             prefixLen = 0;        /* no padding ,this variable to  calculate amount of padding */
933                             formatAttr.flags = 0; /* clear all internal formatAttr.flags */
934                             break;
935                         }
936                     }
937 
938                     case SECUREC_CHAR('p'):
939                         /* print a pointer */
940 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
941                         formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
942 #else
943                         formatAttr.flags |= SECUREC_FLAG_POINTER;
944 #endif
945 
946 #ifdef SECUREC_ON_64BITS
947                         formatAttr.flags |= SECUREC_FLAG_I64; /* converting an int64 */
948 #else
949                         formatAttr.flags |= SECUREC_FLAG_LONG; /* converting a long */
950 #endif
951 
952 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX))
953 
954 #if defined(SECUREC_VXWORKS_PLATFORM)
955                         formatAttr.precision = 1;
956 #else
957                         formatAttr.precision = 0;
958 #endif
959                         formatAttr.flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */
960                         digits = ITOA_LOWER_DIGITS;
961                         goto OUTPUT_HEX;
962 #else
963                                                                /* not linux vxwoks */
964 #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
965                         formatAttr.precision = 1;
966 #else
967                         formatAttr.precision = 2 * sizeof(void *);   /* 2 x byte number is the length of hex */
968 #endif
969 
970 #endif
971 
972 #if defined(SECUREC_ON_UNIX)
973                         digits = ITOA_LOWER_DIGITS;
974                         goto OUTPUT_HEX;
975 #endif
976 
977                         /* fall-through */
978                         /* FALLTHRU */
979                     case SECUREC_CHAR('X'):
980                         /* unsigned upper hex output */
981                         digits = ITOA_UPPER_DIGITS;
982                         goto OUTPUT_HEX;
983 
984                     case SECUREC_CHAR('x'):
985                         /* unsigned lower hex output */
986                         digits = ITOA_LOWER_DIGITS;
987 
988                     OUTPUT_HEX:
989                         radix = 16; /* The radix number of 'x' or 'X' is 16 */
990                         if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
991                             /* alternate form means '0x' prefix */
992                             prefix[0] = SECUREC_CHAR('0');
993                             prefix[1] = (SecChar)(digits[16]); /* The serial number of 'x' or 'X' is 16 */
994 
995 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))
996                             if (ch == 'p') {
997                                 prefix[1] = SECUREC_CHAR('x');
998                             }
999 #endif
1000 #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
1001                             if (ch == 'p') {
1002                                 prefixLen = 0;
1003                             } else {
1004                                 prefixLen = 2; /* securec prefix len is 2 */
1005                             }
1006 #else
1007                             prefixLen = 2; /* securec prefix len is 2 */
1008 #endif
1009                         }
1010                         goto OUTPUT_INT;
1011                     case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
1012                     case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
1013                         /* signed decimal output */
1014                         formatAttr.flags |= SECUREC_FLAG_SIGNED;
1015                         /* fall-through */
1016                         /* FALLTHRU */
1017                     case SECUREC_CHAR('u'):
1018                         radix = 10; /* The radix number of 'u' is 10 */
1019                         goto OUTPUT_INT;
1020                     case SECUREC_CHAR('o'):
1021                         /* unsigned octal output */
1022                         radix = 8; /* The radix number of 'o' is 8 */
1023                         if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
1024                             /* alternate form means force a leading 0 */
1025                             formatAttr.flags |= SECUREC_FLAG_FORCE_OCTAL;
1026                         }
1027                     OUTPUT_INT : {
1028                         SecUnsignedInt64 number = 0; /* number to convert */
1029                         SecInt64 l;                  /* temp long value */
1030                         unsigned char tch;
1031 #if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
1032                         SecUnsignedInt32 digit = 0; /* ascii value of digit */
1033                         SecUnsignedInt32 quotientHigh = 0;
1034                         SecUnsignedInt32 quotientLow = 0;
1035 #endif
1036 
1037                         /* read argument into variable l */
1038                         if (formatAttr.flags & SECUREC_FLAG_I64) {
1039                             l = (SecInt64)va_arg(arglist, SecInt64);
1040                         } else if (formatAttr.flags & SECUREC_FLAG_LONGLONG) {
1041                             l = (SecInt64)va_arg(arglist, SecInt64);
1042                         } else
1043 #ifdef SECUREC_ON_64BITS
1044                             if (formatAttr.flags & SECUREC_FLAG_LONG) {
1045                             l = (long)va_arg(arglist, long);
1046                         } else
1047 #endif /* SECUREC_ON_64BITS */
1048                             if (formatAttr.flags & SECUREC_FLAG_CHAR) {
1049                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1050                                 l = (char)va_arg(arglist, int); /* sign extend */
1051                                 if (l >= 128) {                 /* 128 on some platform, char is always unsigned */
1052                                     SecUnsignedInt64 tmpL = (SecUnsignedInt64)l;
1053                                     formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
1054                                     tch = (unsigned char)(~(tmpL));
1055                                     l = tch + 1;
1056                                 }
1057                             } else {
1058                                 l = (unsigned char)va_arg(arglist, int); /* zero-extend */
1059                             }
1060                         } else if (formatAttr.flags & SECUREC_FLAG_SHORT) {
1061                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1062                                 l = (short)va_arg(arglist, int); /* sign extend */
1063                             } else {
1064                                 l = (unsigned short)va_arg(arglist, int); /* zero-extend */
1065                             }
1066                         }
1067 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
1068                         else if (formatAttr.flags & SECUREC_FLAG_PTRDIFF) {
1069                             l = (ptrdiff_t)va_arg(arglist, ptrdiff_t); /* sign extend */
1070                         } else if (formatAttr.flags & SECUREC_FLAG_SIZE) {
1071                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1072                                 /* No suitable macros were found to handle the branch */
1073                                 if (SecIsSameSize(sizeof(size_t), sizeof(long))) {
1074                                     l = va_arg(arglist, long); /* sign extend */
1075                                 } else if (SecIsSameSize(sizeof(size_t), sizeof(long long))) {
1076                                     l = va_arg(arglist, long long); /* sign extend */
1077                                 } else {
1078                                     l = va_arg(arglist, int); /* sign extend */
1079                                 }
1080                             } else {
1081                                 l = (SecInt64)(size_t)va_arg(arglist, size_t); /* sign extend */
1082                             }
1083                         } else if (formatAttr.flags & SECUREC_FLAG_INTMAX) {
1084                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1085                                 l = va_arg(arglist, SecInt64); /* sign extend */
1086                             } else {
1087                                 l = (SecInt64)(SecUnsignedInt64)va_arg(arglist, SecUnsignedInt64); /* sign extend */
1088                             }
1089                         }
1090 #endif
1091                         else {
1092                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1093                                 l = va_arg(arglist, int); /* sign extend */
1094                             } else {
1095                                 l = (unsigned int)va_arg(arglist, int); /* zero-extend */
1096                             }
1097                         }
1098 
1099                         /* check for negative; copy into number */
1100                         if ((formatAttr.flags & SECUREC_FLAG_SIGNED) && l < 0) {
1101                             number = (SecUnsignedInt64)(-l);
1102                             formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
1103                         } else {
1104                             number = (SecUnsignedInt64)l;
1105                         }
1106 
1107                         if (((formatAttr.flags & SECUREC_FLAG_I64) == 0) &&
1108 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
1109                             ((formatAttr.flags & SECUREC_FLAG_INTMAX) == 0) &&
1110 #endif
1111 #ifdef SECUREC_ON_64BITS
1112                             ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) == 0) &&
1113                             ((formatAttr.flags & SECUREC_FLAG_SIZE) == 0) &&
1114 #if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */
1115                             ((formatAttr.flags & SECUREC_FLAG_LONG) == 0) &&
1116 #endif
1117 #endif
1118                             ((formatAttr.flags & SECUREC_FLAG_LONGLONG) == 0)) {
1119 
1120                             number &= 0xffffffff;
1121                         }
1122 
1123                         /* check precision value for default */
1124                         if (formatAttr.precision < 0) {
1125                             formatAttr.precision = 1; /* default precision */
1126                         } else {
1127 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
1128                             formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1129 #else
1130                             if (!(formatAttr.flags & SECUREC_FLAG_POINTER)) {
1131                                 formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1132                             }
1133 #endif
1134                             if (formatAttr.precision > SECUREC_MAX_PRECISION) {
1135                                 formatAttr.precision = SECUREC_MAX_PRECISION;
1136                             }
1137                         }
1138 
1139                         /* Check if data is 0; if so, turn off hex prefix,if 'p',add 0x prefix,else not add prefix */
1140                         if (number == 0) {
1141 #if !(defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux))
1142                             prefixLen = 0;
1143 #else
1144                             if ((ch == 'p') && (formatAttr.flags & SECUREC_FLAG_ALTERNATE))
1145                                 prefixLen = 2;
1146                             else
1147                                 prefixLen = 0;
1148 #endif
1149                         }
1150 
1151                         /* Convert data to ASCII */
1152                         formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE];
1153 
1154                         if (number > 0) {
1155 #ifdef SECUREC_ON_64BITS
1156                             switch (radix) {
1157                                 /* the compiler will optimize each one */
1158                                 SECUREC_SPECIAL(number, 10);
1159                                 break;
1160                                 SECUREC_SPECIAL(number, 16);
1161                                 break;
1162                                 SECUREC_SPECIAL(number, 8);
1163                                 break;
1164                                 default:
1165                                     break;
1166                             }
1167 #else /* for 32 bits system */
1168                             if (number <= 0xFFFFFFFFUL) {
1169                                 /* in most case, the value to be converted is small value */
1170                                 SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;
1171                                 switch (radix) {
1172                                     SECUREC_SPECIAL(n32Tmp, 16);
1173                                     break;
1174                                     SECUREC_SPECIAL(n32Tmp, 8);
1175                                     break;
1176 
1177 #ifdef _AIX
1178                                     /* the compiler will optimize div 10 */
1179                                     SECUREC_SPECIAL(n32Tmp, 10);
1180                                     break;
1181 #else
1182                                     case 10: { /* securec radix decimal is 10 */
1183                                         /* fast div 10 */
1184                                         SecUnsignedInt32 q;
1185                                         SecUnsignedInt32 r;
1186                                         do {
1187                                             *--formatBuf.str = digits[n32Tmp % 10]; /* securec radix decimal is 10 */
1188                                             q = (n32Tmp >> 1) + (n32Tmp >> 2); /* Fast div  magic 2 */
1189                                             q = q + (q >> 4); /* Fast div  magic 4 */
1190                                             q = q + (q >> 8); /* Fast div  magic 8 */
1191                                             q = q + (q >> 16); /* Fast div  magic 16 */
1192                                             q = q >> 3; /* Fast div  magic 3 */
1193                                             r = n32Tmp - (((q << 2) + q) << 1);
1194                                             n32Tmp = (r > 9) ? (q + 1) : q; /* Fast div  magic 9 */
1195                                         } while (n32Tmp != 0);
1196                                     } break;
1197 #endif
1198                                     default:
1199                                         break;
1200                                 } /* end switch */
1201                             } else {
1202                                 /* the value to be converted is greater than 4G */
1203 #if defined(SECUREC_VXWORKS_VERSION_5_4)
1204                                 do {
1205                                     if (0 != SecU64Div32((SecUnsignedInt32)((number >> 16) >> 16), /* 16, High 32 bit mask */
1206                                         (SecUnsignedInt32)number, (SecUnsignedInt32)radix, &quotientHigh, &quotientLow,
1207                                         &digit)) {
1208                                         noOutput = 1;
1209                                         break;
1210                                     }
1211                                     *--formatBuf.str = digits[digit];
1212 
1213                                     number = (SecUnsignedInt64)quotientHigh;
1214                                     number = (number << 32) + quotientLow; /* High 32 bit mask */
1215                                 } while (number != 0);
1216 #else
1217                                 switch (radix) {
1218                                     /* the compiler will optimize div 10 */
1219                                     SECUREC_SPECIAL(number, 10);
1220                                     break;
1221                                     SECUREC_SPECIAL(number, 16);
1222                                     break;
1223                                     SECUREC_SPECIAL(number, 8);
1224                                     break;
1225                                     default:
1226                                         break;
1227                                 }
1228 #endif
1229                             }
1230 #endif
1231                         } /* END if (number > 0) */
1232                         /* compute length of number,.if textLen > 0, then formatBuf.str must be in buffer.str */
1233                         textLen = (int)((char *)&buffer.str[SECUREC_BUFFER_SIZE] - formatBuf.str);
1234                         if (formatAttr.precision > textLen) {
1235                             for (ii = 0; ii < formatAttr.precision - textLen; ++ii) {
1236                                 *--formatBuf.str = '0';
1237                             }
1238                             textLen = formatAttr.precision;
1239                         }
1240 
1241                         /* Force a leading zero if FORCEOCTAL flag set */
1242                         if ((formatAttr.flags & SECUREC_FLAG_FORCE_OCTAL) &&
1243                             (textLen == 0 || formatBuf.str[0] != '0')) {
1244                             *--formatBuf.str = '0';
1245                             ++textLen; /* add a zero */
1246                         }
1247                     }
1248                     break;
1249                     default:
1250                         break;
1251                 }
1252 
1253                 if (noOutput == 0) {
1254                     if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1255                         if (formatAttr.flags & SECUREC_FLAG_NEGATIVE) {
1256                             /* prefix is a '-' */
1257                             prefix[0] = SECUREC_CHAR('-');
1258                             prefixLen = 1;
1259                         } else if (formatAttr.flags & SECUREC_FLAG_SIGN) {
1260                             /* prefix is '+' */
1261                             prefix[0] = SECUREC_CHAR('+');
1262                             prefixLen = 1;
1263                         } else if (formatAttr.flags & SECUREC_FLAG_SIGN_SPACE) {
1264                             /* prefix is ' ' */
1265                             prefix[0] = SECUREC_CHAR(' ');
1266                             prefixLen = 1;
1267                         }
1268                     }
1269 
1270 #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))
1271                     if ((formatAttr.flags & SECUREC_FLAG_POINTER) && (0 == textLen)) {
1272                         formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1273                         formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE - 1];
1274                         *formatBuf.str-- = '\0';
1275                         *formatBuf.str-- = ')';
1276                         *formatBuf.str-- = 'l';
1277                         *formatBuf.str-- = 'i';
1278                         *formatBuf.str-- = 'n';
1279                         *formatBuf.str = '(';
1280                         textLen = 5; /* Length of (nil) is 5 */
1281                     }
1282 #endif
1283 
1284                     /* calculate amount of padding */
1285                     padding = (formatAttr.fldWidth - textLen) - prefixLen;
1286 
1287                     /* put out the padding, prefix, and text, in the correct order */
1288 
1289                     if (!(formatAttr.flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) && padding > 0) {
1290                         /* pad on left with blanks */
1291                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1292                             /* char * cast to wchar * */
1293                             SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
1294                         } else {
1295                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
1296                         }
1297                     }
1298 
1299                     /* write prefix */
1300                     if (prefixLen > 0) {
1301                         SecChar *pPrefix = prefix;
1302                         if (SECUREC_IS_REST_BUF_ENOUGH(prefixLen)) {
1303                             /* max prefix len is 2, use loop copy */ /* char * cast to wchar * */
1304                             SECUREC_SAFE_WRITE_PREFIX(pPrefix, prefixLen, stream, &charsOut);
1305                         } else {
1306                             SECUREC_WRITE_STRING(prefix, prefixLen, stream, &charsOut);
1307                         }
1308                     }
1309 
1310                     if ((formatAttr.flags & SECUREC_FLAG_LEADZERO) && !(formatAttr.flags & SECUREC_FLAG_LEFT) &&
1311                         padding > 0) {
1312                         /* write leading zeros */
1313                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1314                             /* char * cast to wchar * */
1315                             SECUREC_SAFE_PADDING(SECUREC_CHAR('0'), padding, stream, &charsOut);
1316                         } else {
1317                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR('0'), padding, stream, &charsOut);
1318                         }
1319                     }
1320 
1321                     /* write text */
1322 #ifndef SECUREC_FOR_WCHAR
1323                     if (!isDebugMode && isPrivacy) {
1324                         if (formatAttr.bufferIsWide) {
1325                             formatBuf.wStr = WPRIVACY_STRING;
1326                             textLen = sizeof(WPRIVACY_STRING) / sizeof(wchar_t) - 1;
1327                         } else {
1328                             formatBuf.str = PRIVACY_STRING;
1329                             textLen = strlen(PRIVACY_STRING);
1330                         }
1331                     }
1332                     if (formatAttr.bufferIsWide && (textLen > 0)) {
1333                         wchar_t *p = formatBuf.wStr;
1334                         int count = textLen;
1335                         while (count--) {
1336                             char tmpBuf[SECUREC_MB_LEN + 1];
1337                             // SECUREC_MASK_MSVC_CRT_WARNING
1338                             int retVal = wctomb(tmpBuf, *p++);
1339                             // SECUREC_END_MASK_MSVC_CRT_WARNING
1340                             if (retVal <= 0) {
1341                                 charsOut = -1;
1342                                 break;
1343                             }
1344                             SECUREC_WRITE_STRING(tmpBuf, retVal, stream, &charsOut);
1345                         }
1346                     } else {
1347                         if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
1348                             SECUREC_SAFE_WRITE_STR(formatBuf.str, textLen, stream, &charsOut);
1349                         } else {
1350                             SECUREC_WRITE_STRING(formatBuf.str, textLen, stream, &charsOut);
1351                         }
1352                     }
1353 #else /* SECUREC_FOR_WCHAR */
1354                     if (formatAttr.bufferIsWide == 0 && textLen > 0) {
1355                         int count = textLen;
1356                         char *p = formatBuf.str;
1357 
1358                         while (count > 0) {
1359                             wchar_t wchar = L'\0';
1360                             int retVal = mbtowc(&wchar, p, (size_t)MB_CUR_MAX);
1361                             if (retVal <= 0) {
1362                                 charsOut = -1;
1363                                 break;
1364                             }
1365                             SECUREC_WRITE_CHAR(wchar, stream, &charsOut);
1366                             p += retVal;
1367                             count -= retVal;
1368                         }
1369                     } else {
1370                         if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
1371                             SECUREC_SAFE_WRITE_STR(formatBuf.wStr, textLen, stream,
1372                                 &charsOut); /* char * cast to wchar * */
1373                         } else {
1374                             SECUREC_WRITE_STRING(formatBuf.wStr, textLen, stream, &charsOut);
1375                         }
1376                     }
1377 #endif /* SECUREC_FOR_WCHAR */
1378 
1379                     if (charsOut >= 0 && (formatAttr.flags & SECUREC_FLAG_LEFT) && padding > 0) {
1380                         /* pad on right with blanks */
1381                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1382                             /* char * cast to wchar * */
1383                             SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
1384                         } else {
1385                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
1386                         }
1387                     }
1388 
1389                     /* we're done! */
1390                 }
1391                 if (floatBuf != NULL) {
1392                     SECUREC_FREE(floatBuf);
1393                     floatBuf = NULL;
1394                 }
1395                 break;
1396             case STAT_INVALID:
1397                 return -1;
1398             default:
1399                 return -1; /* input format is wrong, directly return */
1400         }
1401     }
1402 
1403     if (state != STAT_NORMAL && state != STAT_TYPE) {
1404         return -1;
1405     }
1406 
1407     return charsOut; /* the number of characters written */
1408 } /* arglist must not be declare as const */
1409 
1410 
HiLogSecVsnprintfImpl(char * string,size_t count,bool isDebugMode,const char * format,va_list arglist)1411 int HiLogSecVsnprintfImpl(char *string, size_t count, bool isDebugMode, const char *format, va_list arglist)
1412 {
1413     SecPrintfStream str;
1414     int retVal;
1415 
1416     str.count = (int)count; /* this count include \0 character */
1417     str.cur = string;
1418 
1419     retVal = HiLogSecOutputS(&str, isDebugMode, format, arglist);
1420     if (retVal >= 0) {
1421         if (SECUREC_PUTC_ZERO(&str) != EOF) {
1422             return retVal;
1423         }
1424     } else if (str.count < 0) {
1425         /* the buffer was too small; we return truncation */
1426         string[count - 1] = 0;
1427         return SECUREC_PRINTF_TRUNCATE;
1428     }
1429 
1430     return -1;
1431 }
1432 
1433 
HiLog_Printf(char * strDest,size_t destMax,size_t count,bool isDebugMode,const char * format,va_list arglist)1434 int HiLog_Printf(char *strDest, size_t destMax, size_t count, bool isDebugMode, const char *format, va_list arglist)
1435 {
1436     int retVal;
1437 
1438     if (format == NULL || strDest == NULL || destMax == 0 || destMax > SECUREC_STRING_MAX_LEN ||
1439         (count > (SECUREC_STRING_MAX_LEN - 1) && count != (size_t)-1)) {
1440         if (strDest != NULL && destMax > 0) {
1441             strDest[0] = '\0';
1442         }
1443         SECUREC_ERROR_INVALID_PARAMTER("hilog_printf");
1444         return -1;
1445     }
1446 
1447     if (destMax > count) {
1448         retVal = HiLogSecVsnprintfImpl(strDest, count + 1, isDebugMode, format, arglist);
1449         if (retVal == SECUREC_PRINTF_TRUNCATE) { /* lsd add to keep dest buffer not destroyed 2014.2.18 */
1450             /* the string has been truncated, return  -1 */
1451             return -1; /* to skip error handler,  return strlen(strDest) or -1 */
1452         }
1453     } else { /* destMax <= count */
1454         retVal = HiLogSecVsnprintfImpl(strDest, destMax, isDebugMode, format, arglist);
1455 #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
1456         if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)-1) {
1457             return -1;
1458         }
1459 #endif
1460     }
1461 
1462     if (retVal < 0) {
1463         strDest[0] = '\0'; /* empty the dest strDest */
1464 
1465         if (retVal == SECUREC_PRINTF_TRUNCATE) {
1466             /* Buffer too small */
1467             SECUREC_ERROR_INVALID_RANGE("hilog_printf");
1468         }
1469 
1470         SECUREC_ERROR_INVALID_PARAMTER("hilog_printf");
1471         return -1;
1472     }
1473 
1474     return retVal;
1475 }
1476 
1477 #define HILOG_DRIVER "/dev/hilog"
1478 static char g_logLevelInfo[HILOG_LEVEL_MAX] = {
1479     'N', // "NONE"
1480     'N', // "NONE"
1481     'N', // "NONE"
1482     'D', // "DEBUG"
1483     'I', // "INFO"
1484     'W', // "WARN"
1485     'E', // "ERROR"
1486     'F'  // "FATAL"
1487 };
1488 
1489 #ifdef LOSCFG_BASE_CORE_HILOG
1490 extern int HiLogWriteInternal(const char *buffer, size_t bufLen);
1491 #else
1492 static int g_hilogFd = -1;
1493 #endif
1494 
HiLogPrintArgs(LogType bufID,LogLevel prio,unsigned int domain,const char * tag,const char * fmt,va_list ap)1495 int HiLogPrintArgs(LogType bufID, LogLevel prio, unsigned int domain, const char *tag, const char *fmt, va_list ap)
1496 {
1497     int ret;
1498     char buf[LOG_BUF_SIZE] = {0};
1499     bool isDebugMode = 1;
1500     unsigned int bufLen;
1501     (void)bufID;
1502 
1503 #ifdef OHOS_RELEASE
1504     isDebugMode = 0;
1505 #endif
1506 #ifdef DISABLE_HILOG_PRIVACY
1507     isDebugMode = 1;
1508 #endif
1509     if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%c %05X/%s: ", g_logLevelInfo[prio], (domain & DOMAIN_FILTER),
1510         tag) == -1) {
1511         return 0;
1512     }
1513 
1514     bufLen = strlen(buf);
1515     if (bufLen >= MAX_DOMAIN_TAG_SIZE) {
1516         return 0;
1517     }
1518 
1519 #ifndef LOSCFG_BASE_CORE_HILOG
1520     /* print traceid */
1521     if (g_registerFunc != NULL) {
1522         char *logBuf = buf;
1523         int traceBufLen = 0;
1524         uint64_t chainId = 0;
1525         uint32_t flag = 0;
1526         uint64_t spanId = 0;
1527         uint64_t parentSpanId = 0;
1528         ret = -1;  /* default value -1: invalid trace id */
1529         atomic_fetch_add_explicit(&g_hiLogGetIdCallCount, 1, memory_order_relaxed);
1530         RegisterFunc func = g_registerFunc;
1531         if (g_registerFunc != NULL) {
1532             ret = func(&chainId, &flag, &spanId, &parentSpanId);
1533         }
1534         atomic_fetch_sub_explicit(&g_hiLogGetIdCallCount, 1, memory_order_relaxed);
1535         if (ret == 0) {  /* 0: trace id with span id */
1536             traceBufLen = snprintf_s(logBuf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, "[%llx, %llx, %llx] ",
1537                 (unsigned long long)chainId, (unsigned long long)spanId, (unsigned long long)parentSpanId);
1538         } else if (ret != -1) {  /* trace id without span id, -1: invalid trace id */
1539             traceBufLen = snprintf_s(logBuf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, "[%llx] ",
1540                 (unsigned long long)chainId);
1541         }
1542         if (traceBufLen > 0) {
1543             logBuf += traceBufLen;
1544         } else {
1545             traceBufLen = 0;
1546         }
1547     }
1548 #endif
1549 
1550     HiLog_Printf(buf + bufLen, LOG_BUF_SIZE - bufLen, LOG_BUF_SIZE - bufLen - 1, isDebugMode, fmt, ap);
1551 
1552 #ifdef LOSCFG_BASE_CORE_HILOG
1553     ret = HiLogWriteInternal(buf, strlen(buf) + 1);
1554 #else
1555     if (g_hilogFd == -1) {
1556         g_hilogFd = open(HILOG_DRIVER, O_WRONLY | O_CLOEXEC);
1557     }
1558     if (g_hilogFd == -1) {
1559         return 0;
1560     }
1561     ret = write(g_hilogFd, buf, strlen(buf) + 1);
1562 #endif
1563     return ret;
1564 }
1565 
HiLogPrint(LogType bufID,LogLevel prio,unsigned int domain,const char * tag,const char * fmt,...)1566 int HiLogPrint(LogType bufID, LogLevel prio, unsigned int domain, const char *tag, const char *fmt, ...)
1567 {
1568     int ret;
1569     va_list ap;
1570     va_start(ap, fmt);
1571     ret = HiLogPrintArgs(bufID, prio, domain, tag, fmt, ap);
1572     va_end(ap);
1573     return ret;
1574 }
1575 
FlushHilog(void)1576 int FlushHilog(void)
1577 {
1578     int ret;
1579 #define FLUSH_LOG_WRITE_LEN 3
1580     char buf[FLUSH_LOG_WRITE_LEN] = {0x07, 0x07, '\0'};
1581 #ifdef LOSCFG_BASE_CORE_HILOG
1582     ret = HiLogWriteInternal(buf, strlen(buf) + 1);
1583 #else
1584     if (g_hilogFd == -1) {
1585         g_hilogFd = open(HILOG_DRIVER, O_WRONLY);
1586     }
1587     if (g_hilogFd == -1) {
1588         return 0;
1589     }
1590     ret = write(g_hilogFd, buf, strlen(buf) + 1);
1591 #endif
1592     return ret;
1593 }
1594