Mercurial > pub > halpp
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 } |