1 /*********************************************************************************************************//**
2 * @file printf.c
3 * @version $Rev:: 93 $
4 * @date $Date:: 2015-11-24 #$
5 * @brief Print functions.
6 *************************************************************************************************************
7 * @attention
8 *
9 * Firmware Disclaimer Information
10 *
11 * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12 * code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13 * proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14 * other intellectual property laws.
15 *
16 * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17 * code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18 * other than HOLTEK and the customer.
19 *
20 * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21 * only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22 * the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23 * the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24 *
25 * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26 ************************************************************************************************************/
27
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32.h"
30 #include <string.h>
31
32 /** @addtogroup HT32_Peripheral_Driver HT32 Peripheral Driver
33 * @{
34 */
35
36 /** @defgroup PRINTF printf re-implementation
37 * @brief printf related functions
38 * @{
39 */
40
41
42 /* Private macro -------------------------------------------------------------------------------------------*/
43 /** @defgroup PRINTF_Private_Macro printf private macros
44 * @{
45 */
46 #define vaStart(list, param) list = (char*)((int)¶m + sizeof(param))
47 #define vaArg(list, type) ((type *)(list += sizeof(type)))[-1]
48 /**
49 * @}
50 */
51
52 /* Private function prototypes -----------------------------------------------------------------------------*/
53 static const char *FormatItem(const char *f, int a);
54 static void PutRepChar(const char c, int count);
55 static int PutString(const char *pString);
56 static int PutStringReverse(const char *pString, int index);
57 static void PutNumber(int value, int radix, int width, char fill);
58
59 /* Global functions ----------------------------------------------------------------------------------------*/
60 /** @defgroup PRINTF_Exported_Functions printf exported functions
61 * @{
62 */
63 /*********************************************************************************************************//**
64 * @brief Print function.
65 * @param f: Format string.
66 * @retval String length.
67 ************************************************************************************************************/
printf(const char * f,...)68 signed int printf(const char *f, ...)
69 {
70 char *argP;
71 int i = 0;
72
73 vaStart(argP, f);
74 while (*f)
75 {
76 if (*f == '%')
77 {
78 f = FormatItem(f + 1, vaArg(argP, int));
79 }
80 else
81 {
82 fputc(*f++, (FILE *)1);
83 }
84 i++;
85 }
86 return i;
87 }
88
89 /*********************************************************************************************************//**
90 * @brief Put string.
91 * @param pString: String.
92 * @retval String length.
93 ************************************************************************************************************/
puts(const char * pString)94 signed int puts(const char *pString)
95 {
96 int i;
97 i = PutString(pString);
98 fputc('\n', (FILE *)1);
99 return i;
100 }
101 /**
102 * @}
103 */
104
105 /* Private functions ---------------------------------------------------------------------------------------*/
106 /** @defgroup PRINTF_Private_Function printf private functions
107 * @{
108 */
109 /*********************************************************************************************************//**
110 * @brief Format item for print function.
111 * @param f: Format string.
112 * @param a: Length of format string.
113 * @retval Point of string.
114 ************************************************************************************************************/
FormatItem(const char * f,int a)115 static const char *FormatItem(const char *f, int a)
116 {
117 char c;
118 int fieldwidth = 0;
119 int leftjust = FALSE;
120 int radix = 0;
121 char fill = ' ';
122 int i;
123
124 if (*f == '0')
125 {
126 fill = '0';
127 }
128
129 while ((c = *f++) != 0)
130 {
131 if (c >= '0' && c <= '9')
132 {
133 fieldwidth = (fieldwidth * 10) + (c - '0');
134 }
135 else
136 {
137 switch (c)
138 {
139 case '\000':
140 {
141 return (--f);
142 }
143 case '%':
144 {
145 fputc('%', (FILE *)1);
146 return (f);
147 }
148 case '-':
149 {
150 leftjust = TRUE;
151 break;
152 }
153 case 'c':
154 {
155 if (leftjust)
156 {
157 fputc(a & 0x7f, (FILE *)f);
158 }
159 if (fieldwidth > 0)
160 {
161 PutRepChar(fill, fieldwidth - 1);
162 }
163 if (!leftjust)
164 {
165 fputc(a & 0x7f, (FILE *)f);
166 return (f);
167 }
168 }
169 case 's':
170 {
171 i = 0;
172 while (*((char *)(a + i)) !='\0' )
173 {
174 i++;
175 }
176
177 if (leftjust)
178 {
179 PutString((char *)a);
180 }
181
182 if (fieldwidth > i )
183 {
184 PutRepChar(fill, fieldwidth - i);
185 }
186
187 if (!leftjust)
188 {
189 PutString((char *)a);
190 }
191 return (f);
192 }
193 case 'l':
194 {
195 radix = -10;
196 f++;
197 break;
198 }
199 case 'd':
200 case 'i':
201 {
202 radix = -10;
203 break;
204 }
205 case 'u':
206 {
207 radix = 10;
208 break;
209 }
210 case 'x':
211 case 'X':
212 {
213 radix = 16;
214 break;
215 }
216 case 'o':
217 {
218 radix = 8;
219 break;
220 }
221 default:
222 {
223 radix = 3;
224 break;
225 }
226 }
227 }
228 if (radix)
229 {
230 break;
231 }
232 }
233
234 if (leftjust)
235 {
236 fieldwidth = -fieldwidth;
237 }
238
239 PutNumber(a, radix, fieldwidth, fill);
240
241 return (f);
242 }
243
244 /*********************************************************************************************************//**
245 * @brief Put repeat character.
246 * @param c: Character.
247 * @param count: Repeat count
248 ************************************************************************************************************/
PutRepChar(const char c,int count)249 static void PutRepChar(const char c, int count)
250 {
251 while (count--)
252 {
253 fputc(c, (FILE *)1);
254 }
255 }
256
257 /*********************************************************************************************************//**
258 * @brief Put string.
259 * @param pString: String.
260 * @retval String length.
261 ************************************************************************************************************/
PutString(const char * pString)262 static int PutString(const char *pString)
263 {
264 int i = 0;
265 while (*pString != '\0')
266 {
267 fputc(*pString, (FILE *)1);
268 pString++;
269 i++;
270 }
271
272 return i;
273 }
274
275 /*********************************************************************************************************//**
276 * @brief Put string in reversed order.
277 * @param pString: String.
278 * @param index: String length
279 * @retval String length.
280 ************************************************************************************************************/
PutStringReverse(const char * pString,int index)281 static int PutStringReverse(const char *pString, int index)
282 {
283 int i = 0;
284 while ((index--) > 0)
285 {
286 fputc(pString[index], (FILE *)1);
287 i++;
288 }
289 return i;
290 }
291
292 /*********************************************************************************************************//**
293 * @brief Put number.
294 * @param value: Value of number.
295 * @param radix: Radix of number.
296 * @param width: Width of number.
297 * @param fill: fill character.
298 ************************************************************************************************************/
PutNumber(int value,int radix,int width,char fill)299 static void PutNumber(int value, int radix, int width, char fill)
300 {
301 char buffer[8];
302 int bi = 0;
303 unsigned int uvalue;
304 unsigned short digit;
305 unsigned short left = FALSE;
306 unsigned short negative = FALSE;
307
308 if (fill == 0)
309 {
310 fill = ' ';
311 }
312
313 if (width < 0)
314 {
315 width = -width;
316 left = TRUE;
317 }
318
319 if (width < 0 || width > 80)
320 {
321 width = 0;
322 }
323
324 if (radix < 0)
325 {
326 radix = -radix;
327 if (value < 0)
328 {
329 negative = TRUE;
330 value = -value;
331 }
332 }
333
334 uvalue = value;
335
336 do
337 {
338 if (radix != 16)
339 {
340 digit = uvalue % radix;
341 uvalue = uvalue / radix;
342 }
343 else
344 {
345 digit = uvalue & 0xf;
346 uvalue = uvalue >> 4;
347 }
348 buffer[bi] = digit + ((digit <= 9) ? '0' : ('A' - 10));
349 bi++;
350 }
351 while (uvalue != 0);
352
353 if (negative)
354 {
355 buffer[bi] = '-';
356 bi += 1;
357 }
358
359 if (width <= bi)
360 {
361 PutStringReverse(buffer, bi);
362 }
363 else
364 {
365 width -= bi;
366 if (!left)
367 {
368 PutRepChar(fill, width);
369 }
370
371 PutStringReverse(buffer, bi);
372
373 if (left)
374 {
375 PutRepChar(fill, width);
376 }
377 }
378 }
379 /**
380 * @}
381 */
382
383
384 /**
385 * @}
386 */
387
388 /**
389 * @}
390 */
391