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)&param + 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