1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
3 * Licensed under Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 * Description: By defining corresponding macro for ANSI string and including "output.inl",
12 * this file generates real underlying function used by printf family API.
13 * Create: 2014-02-25
14 */
15
16 #define SECUREC_FORMAT_OUTPUT_INPUT 1
17
18 #ifdef SECUREC_FOR_WCHAR
19 #undef SECUREC_FOR_WCHAR
20 #endif
21
22 #include "secureprintoutput.h"
23 #if SECUREC_WARP_OUTPUT
24 #define SECUREC_FORMAT_FLAG_TABLE_SIZE 128
SecSkipKnownFlags(const char * format)25 SECUREC_INLINE const char *SecSkipKnownFlags(const char *format)
26 {
27 static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {
28 /*
29 * Known flag is "0123456789 +-#hlLwZzjqt*I$"
30 */
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
34 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
38 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
39 };
40 const char *fmt = format;
41 while (*fmt != '\0') {
42 char fmtChar = *fmt;
43 if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */
44 break;
45 }
46 if (flagTable[(unsigned char)fmtChar] == 0) {
47 break;
48 }
49 ++fmt;
50 }
51 return fmt;
52 }
53
SecFormatContainN(const char * format)54 SECUREC_INLINE int SecFormatContainN(const char *format)
55 {
56 const char *fmt = format;
57 while (*fmt != '\0') {
58 ++fmt;
59 /* Skip normal char */
60 if (*(fmt - 1) != '%') {
61 continue;
62 }
63 /* Meet %% */
64 if (*fmt == '%') {
65 ++fmt; /* Point to the character after the %. Correct handling %%xx */
66 continue;
67 }
68 /* Now parse %..., fmt point to the character after the % */
69 fmt = SecSkipKnownFlags(fmt);
70 if (*fmt == 'n') {
71 return 1;
72 }
73 }
74 return 0;
75 }
76 /*
77 * Multi character formatted output implementation, the count include \0 character, must be greater than zero
78 */
SecVsnprintfImpl(char * string,size_t count,const char * format,va_list argList)79 int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
80 {
81 int retVal;
82 if (SecFormatContainN(format) != 0) {
83 string[0] = '\0';
84 return -1;
85 }
86 SECUREC_MASK_VSPRINTF_WARNING
87 retVal = vsnprintf(string, count, format, argList);
88 SECUREC_END_MASK_VSPRINTF_WARNING
89 if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */
90 /* The buffer was too small; we return truncation */
91 string[count - 1] = '\0';
92 return SECUREC_PRINTF_TRUNCATE;
93 }
94 if (retVal < 0) {
95 string[0] = '\0'; /* Empty the dest strDest */
96 return -1;
97 }
98 return retVal;
99 }
100 #else
101 #if SECUREC_IN_KERNEL
102 #include <linux/ctype.h>
103 #endif
104
105 #ifndef EOF
106 #define EOF (-1)
107 #endif
108
109 #include "output.inl"
110
111 #endif
112
113