comparison l476rg-hal-test/src/tiny_printf.c @ 0:32a3b1785697

a rough draft of Hardware Abstraction Layer for C++ STM32L476RG drivers
author cin
date Thu, 12 Jan 2017 02:45:43 +0300
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:32a3b1785697
1 /*
2 ******************************************************************************
3 File: tiny_printf.c
4 Info: Generated by Atollic TrueSTUDIO 7.0.1 2017-01-12
5
6 Abstract: Atollic TrueSTUDIO Minimal iprintf/siprintf/fiprintf
7 and puts/fputs.
8 Provides aliased declarations for printf/sprintf/fprintf
9 pointing to *iprintf variants.
10
11 The argument contains a format string that may include
12 conversion specifications. Each conversion specification
13 is introduced by the character %, and ends with a
14 conversion specifier.
15
16 The following conversion specifiers are supported
17 cdisuxX%
18
19 Usage:
20 c character
21 d,i signed integer (-sign added, + sign not supported)
22 s character string
23 u unsigned integer as decimal
24 x,X unsigned integer as hexadecimal (uppercase letter)
25 % % is written (conversion specification is '%%')
26
27 Note:
28 Character padding is not supported
29
30 The MIT License (MIT)
31 Copyright (c) 2009-2016 Atollic AB
32
33 Permission is hereby granted, free of charge, to any person obtaining a copy
34 of this software and associated documentation files (the "Software"), to deal
35 in the Software without restriction, including without limitation the rights
36 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37 copies of the Software, and to permit persons to whom the Software is
38 furnished to do so, subject to the following conditions:
39
40 The above copyright notice and this permission notice shall be included in all
41 copies or substantial portions of the Software.
42
43 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49 SOFTWARE.
50 ******************************************************************************
51 */
52
53 /* Includes */
54 #include <stdarg.h>
55 #include <stdio.h>
56 #include <string.h>
57
58 /* Create aliases for *printf to integer variants *iprintf */
59 __attribute__ ((alias("iprintf"))) int printf(const char *fmt, ...);
60 __attribute__ ((alias("fiprintf"))) int fprintf(FILE* fp, const char *fmt, ...);
61 __attribute__ ((alias("siprintf"))) int sprintf(char* str, const char *fmt, ...);
62
63 /* External function prototypes (defined in syscalls.c) */
64 extern int _write(int fd, char *str, int len);
65
66 /* Private function prototypes */
67 void ts_itoa(char **buf, unsigned int d, int base);
68 int ts_formatstring(char *buf, const char *fmt, va_list va);
69 int ts_formatlength(const char *fmt, va_list va);
70
71 /* Private functions */
72
73 /**
74 **---------------------------------------------------------------------------
75 ** Abstract: Convert integer to ascii
76 ** Returns: void
77 **---------------------------------------------------------------------------
78 */
79 void ts_itoa(char **buf, unsigned int d, int base)
80 {
81 int div = 1;
82 while (d/div >= base)
83 div *= base;
84
85 while (div != 0)
86 {
87 int num = d/div;
88 d = d%div;
89 div /= base;
90 if (num > 9)
91 *((*buf)++) = (num-10) + 'A';
92 else
93 *((*buf)++) = num + '0';
94 }
95 }
96
97 /**
98 **---------------------------------------------------------------------------
99 ** Abstract: Writes arguments va to buffer buf according to format fmt
100 ** Returns: Length of string
101 **---------------------------------------------------------------------------
102 */
103 int ts_formatstring(char *buf, const char *fmt, va_list va)
104 {
105 char *start_buf = buf;
106 while(*fmt)
107 {
108 /* Character needs formating? */
109 if (*fmt == '%')
110 {
111 switch (*(++fmt))
112 {
113 case 'c':
114 *buf++ = va_arg(va, int);
115 break;
116 case 'd':
117 case 'i':
118 {
119 signed int val = va_arg(va, signed int);
120 if (val < 0)
121 {
122 val *= -1;
123 *buf++ = '-';
124 }
125 ts_itoa(&buf, val, 10);
126 }
127 break;
128 case 's':
129 {
130 char * arg = va_arg(va, char *);
131 while (*arg)
132 {
133 *buf++ = *arg++;
134 }
135 }
136 break;
137 case 'u':
138 ts_itoa(&buf, va_arg(va, unsigned int), 10);
139 break;
140 case 'x':
141 case 'X':
142 ts_itoa(&buf, va_arg(va, int), 16);
143 break;
144 case '%':
145 *buf++ = '%';
146 break;
147 }
148 fmt++;
149 }
150 /* Else just copy */
151 else
152 {
153 *buf++ = *fmt++;
154 }
155 }
156 *buf = 0;
157
158 return (int)(buf - start_buf);
159 }
160
161
162 /**
163 **---------------------------------------------------------------------------
164 ** Abstract: Calculate maximum length of the resulting string from the
165 ** format string and va_list va
166 ** Returns: Maximum length
167 **---------------------------------------------------------------------------
168 */
169 int ts_formatlength(const char *fmt, va_list va)
170 {
171 int length = 0;
172 while (*fmt)
173 {
174 if (*fmt == '%')
175 {
176 ++fmt;
177 switch (*fmt)
178 {
179 case 'c':
180 va_arg(va, int);
181 ++length;
182 break;
183 case 'd':
184 case 'i':
185 case 'u':
186 /* 32 bits integer is max 11 characters with minus sign */
187 length += 11;
188 va_arg(va, int);
189 break;
190 case 's':
191 {
192 char * str = va_arg(va, char *);
193 while (*str++)
194 ++length;
195 }
196 break;
197 case 'x':
198 case 'X':
199 /* 32 bits integer as hex is max 8 characters */
200 length += 8;
201 va_arg(va, unsigned int);
202 break;
203 default:
204 ++length;
205 break;
206 }
207 }
208 else
209 {
210 ++length;
211 }
212 ++fmt;
213 }
214 return length;
215 }
216
217 /**
218 **===========================================================================
219 ** Abstract: Loads data from the given locations and writes them to the
220 ** given character string according to the format parameter.
221 ** Returns: Number of bytes written
222 **===========================================================================
223 */
224 int siprintf(char *buf, const char *fmt, ...)
225 {
226 int length;
227 va_list va;
228 va_start(va, fmt);
229 length = ts_formatstring(buf, fmt, va);
230 va_end(va);
231 return length;
232 }
233
234 /**
235 **===========================================================================
236 ** Abstract: Loads data from the given locations and writes them to the
237 ** given file stream according to the format parameter.
238 ** Returns: Number of bytes written
239 **===========================================================================
240 */
241 int fiprintf(FILE * stream, const char *fmt, ...)
242 {
243 int length = 0;
244 va_list va;
245 va_start(va, fmt);
246 length = ts_formatlength(fmt, va);
247 va_end(va);
248 {
249 char buf[length];
250 va_start(va, fmt);
251 length = ts_formatstring(buf, fmt, va);
252 length = _write(stream->_file, buf, length);
253 va_end(va);
254 }
255 return length;
256 }
257
258 /**
259 **===========================================================================
260 ** Abstract: Loads data from the given locations and writes them to the
261 ** standard output according to the format parameter.
262 ** Returns: Number of bytes written
263 **
264 **===========================================================================
265 */
266 int iprintf(const char *fmt, ...)
267 {
268 int length = 0;
269 va_list va;
270 va_start(va, fmt);
271 length = ts_formatlength(fmt, va);
272 va_end(va);
273 {
274 char buf[length];
275 va_start(va, fmt);
276 length = ts_formatstring(buf, fmt, va);
277 length = _write(1, buf, length);
278 va_end(va);
279 }
280 return length;
281 }
282
283 /**
284 **===========================================================================
285 ** Abstract: fputs writes the string at s (but without the trailing null) to
286 ** the file or stream identified by fp.
287 ** Returns: If successful, the result is 0; otherwise, the result is EOF.
288 **
289 **===========================================================================
290 */
291 int fputs(const char *s, FILE *fp)
292 {
293 int length = strlen(s);
294 int wlen = 0;
295 int res;
296
297 wlen = _write((fp->_file), (char*)s, length);
298 wlen += _write((fp->_file), "\n", 1);
299
300 if (wlen == (length+1))
301 {
302 res = 0;
303 }
304 else
305 {
306 res = EOF;
307 }
308
309 return res;
310 }
311
312 /**
313 **===========================================================================
314 ** Abstract: puts writes the string at s (followed by a newline, instead of
315 ** the trailing null) to the standard output stream.
316 ** Returns: If successful, the result is a nonnegative integer; otherwise,
317 ** the result is EOF.
318 **
319 **===========================================================================
320 */
321 int puts(const char *s)
322 {
323 int length = strlen(s);
324 int numbytes = 0;
325 int res;
326
327 numbytes = _write(1, (char*)s, length);
328 numbytes += _write(1, "\n", 1);
329
330 if (numbytes == (length+1))
331 {
332 res = 0;
333 }
334 else
335 {
336 res = EOF;
337 }
338
339 return res;
340 }
341
342 /**
343 **===========================================================================
344 ** Abstract: Copy, starting from the memory location buf, count elements
345 ** (each of size size) into the file or stream identified by fp.
346 ** Returns: Number of elements written
347 **
348 **===========================================================================
349 */
350 size_t fwrite(const void * buf, size_t size, size_t count, FILE * fp)
351 {
352 return (_write((fp->_file), (char*)buf, size * count) / size);
353 }