APM:Libraries
stdio.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) Siddharth Bharat Purohit 2017
3  * This file is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the
5  * Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This file is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 /*
17  wrappers for stdio functions
18 
19  Relies on linker wrap options
20 
21  Note that not all functions that have been wrapped are implemented
22  here. The others are wrapped to ensure the function is not used
23  without an implementation. If we need them then we can implement as
24  needed.
25  */
26 #include <posix.h>
27 #include <string.h>
28 #include <hal.h>
29 #include <memstreams.h>
30 #include <chprintf.h>
31 #include <ctype.h>
32 #include "stdio.h"
33 
34 int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
35 {
36  MemoryStream ms;
37  BaseSequentialStream *chp;
38  size_t size_wo_nul;
39  int retval;
40 
41  if (size > 0)
42  size_wo_nul = size - 1;
43  else
44  size_wo_nul = 0;
45 
46  /* Memory stream object to be used as a string writer, reserving one
47  byte for the final zero.*/
48  msObjectInit(&ms, (uint8_t *)str, size_wo_nul, 0);
49 
50  /* Performing the print operation using the common code.*/
51  chp = (BaseSequentialStream *)(void *)&ms;
52 
53  retval = chvprintf(chp, fmt, ap);
54 
55 
56  /* Terminate with a zero, unless size==0.*/
57  if (ms.eos < size)
58  str[ms.eos] = 0;
59 
60  /* Return number of bytes that would have been written.*/
61  return retval;
62 }
63 
64 int snprintf(char *str, size_t size, const char *fmt, ...)
65 {
66  va_list arg;
67  int done;
68 
69  va_start (arg, fmt);
70  done = vsnprintf(str, size, fmt, arg);
71  va_end (arg);
72 
73  return done;
74 }
75 
76 int vasprintf(char **strp, const char *fmt, va_list ap)
77 {
78  int len = vsnprintf(NULL, 0, fmt, ap);
79  if (len <= 0) {
80  return -1;
81  }
82  char *buf = calloc(len+1, 1);
83  if (!buf) {
84  return -1;
85  }
86  vsnprintf(buf, len+1, fmt, ap);
87  (*strp) = buf;
88  return len;
89 }
90 
91 int asprintf(char **strp, const char *fmt, ...)
92 {
93  va_list ap;
94  va_start(ap, fmt);
95  int ret = vasprintf(strp, fmt, ap);
96  va_end(ap);
97  return ret;
98 }
99 
100 int vprintf(const char *fmt, va_list arg)
101 {
102 #ifdef HAL_STDOUT_SERIAL
103  return chvprintf ((BaseSequentialStream*)&HAL_STDOUT_SERIAL, fmt, arg);
104 #else
105  (void)arg;
106  return strlen(fmt);
107 #endif
108 }
109 
110 // hook to allow for printf() on systems without HAL_STDOUT_SERIAL
111 int (*vprintf_console_hook)(const char *fmt, va_list arg) = vprintf;
112 
113 int printf(const char *fmt, ...)
114 {
115  va_list arg;
116  int done;
117 
118  va_start (arg, fmt);
119  done = vprintf_console_hook(fmt, arg);
120  va_end (arg);
121 
122  return done;
123 }
124 
125 //just a stub
126 int
127 scanf (const char *fmt, ...)
128 {
129  (void)fmt;
130  return 0;
131 }
132 /*
133  * sscanf(buf,fmt,va_alist)
134  */
135 int
136 sscanf (const char *buf, const char *fmt, ...)
137 {
138  int count;
139  va_list ap;
140 
141  va_start (ap, fmt);
142  count = vsscanf (buf, fmt, ap);
143  va_end (ap);
144  return (count);
145 }
146 
147 static char *
148 _getbase(char *p, int *basep)
149 {
150  if (p[0] == '0') {
151  switch (p[1]) {
152  case 'x':
153  *basep = 16;
154  break;
155  case 't': case 'n':
156  *basep = 10;
157  break;
158  case 'o':
159  *basep = 8;
160  break;
161  default:
162  *basep = 10;
163  return (p);
164  }
165  return (p + 2);
166  }
167  *basep = 10;
168  return (p);
169 }
170 
171 static int16_t
172 _atob (uint32_t *vp, char *p, int base)
173 {
174  uint32_t value, v1, v2;
175  char *q, tmp[20];
176  int digit;
177 
178  if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
179  base = 16;
180  p += 2;
181  }
182 
183  if (base == 16 && (q = strchr (p, '.')) != 0) {
184  if ((unsigned)(q - p) > (unsigned)(sizeof(tmp) - 1))
185  return (0);
186 
187  strncpy (tmp, p, q - p);
188  tmp[q - p] = '\0';
189  if (!_atob (&v1, tmp, 16))
190  return (0);
191 
192  q++;
193  if (strchr (q, '.'))
194  return (0);
195 
196  if (!_atob (&v2, q, 16))
197  return (0);
198  *vp = (v1 << 16) + v2;
199  return (1);
200  }
201 
202  value = *vp = 0;
203  for (; *p; p++) {
204  if (*p >= '0' && *p <= '9')
205  digit = *p - '0';
206  else if (*p >= 'a' && *p <= 'f')
207  digit = *p - 'a' + 10;
208  else if (*p >= 'A' && *p <= 'F')
209  digit = *p - 'A' + 10;
210  else
211  return (0);
212 
213  if (digit >= base)
214  return (0);
215  value *= base;
216  value += digit;
217  }
218  *vp = value;
219  return (1);
220 }
221 
222 /*
223  * atob(vp,p,base)
224  * converts p to binary result in vp, rtn 1 on success
225  */
226 int16_t
227 atob(uint32_t *vp, char *p, int base)
228 {
229  uint32_t v;
230 
231  if (base == 0)
232  p = _getbase (p, &base);
233  if (_atob (&v, p, base)) {
234  *vp = v;
235  return (1);
236  }
237  return (0);
238 }
239 
240 
241 #if defined(HAL_OS_FATFS_IO) && HAL_OS_FATFS_IO
242 /*
243  * vsscanf(buf,fmt,ap)
244  */
245 int
246 vsscanf (const char *buf, const char *s, va_list ap)
247 {
248  int count, noassign, base=0, lflag;
249  uint32_t width;
250  const char *tc;
251  char *t, tmp[MAXLN];
252 
253  count = noassign = width = lflag = 0;
254  while (*s && *buf) {
255  while (isspace ((unsigned char)(*s)))
256  s++;
257  if (*s == '%') {
258  s++;
259  for (; *s; s++) {
260  if (strchr ("dibouxcsefg%", *s))
261  break;
262  if (*s == '*')
263  noassign = 1;
264  else if (*s == 'l' || *s == 'L')
265  lflag = 1;
266  else if (*s >= '1' && *s <= '9') {
267  for (tc = s; isdigit ((unsigned)(*s)); s++);
268  strncpy (tmp, tc, s - tc);
269  tmp[s - tc] = '\0';
270  atob (&width, tmp, 10);
271  s--;
272  }
273  }
274  if (*s == 's') {
275  while (isspace ((unsigned char)(*buf)))
276  buf++;
277  if (!width)
278  width = strcspn (buf, ISSPACE);
279  if (!noassign) {
280  strncpy (t = va_arg (ap, char *), buf, width);
281  t[width] = '\0';
282  }
283  buf += width;
284  } else if (*s == 'c') {
285  if (!width)
286  width = 1;
287  if (!noassign) {
288  strncpy (t = va_arg (ap, char *), buf, width);
289  t[width] = '\0';
290  }
291  buf += width;
292  } else if (strchr ("dobxu", *s)) {
293  while (isspace ((unsigned char)(*buf)))
294  buf++;
295  if (*s == 'd' || *s == 'u')
296  base = 10;
297  else if (*s == 'x')
298  base = 16;
299  else if (*s == 'o')
300  base = 8;
301  else if (*s == 'b')
302  base = 2;
303  if (!width) {
304  if (isspace ((unsigned char)(*(s + 1))) || *(s + 1) == 0)
305  width = strcspn (buf, ISSPACE);
306  else
307  width = strchr (buf, *(s + 1)) - buf;
308  }
309  strncpy (tmp, buf, width);
310  tmp[width] = '\0';
311  buf += width;
312  if (!noassign)
313  atob (va_arg (ap, uint32_t *), tmp, base);
314  }
315  if (!noassign)
316  count++;
317  width = noassign = lflag = 0;
318  s++;
319  } else {
320  while (isspace ((unsigned char)(*buf)))
321  buf++;
322  if (*s != *buf)
323  break;
324  else
325  s++, buf++;
326  }
327  }
328  return (count);
329 }
330 
331 static int vfscanf(FILE *stream, const char *fmt, va_list ap);
332 
333 /*
334  * fscanf(stream,fmt,va_alist)
335  */
336 int fscanf (FILE *stream, const char *fmt, ...)
337 {
338  int count;
339  va_list ap;
340 
341  va_start (ap, fmt);
342  count = vfscanf (stream, fmt, ap);
343  va_end (ap);
344  return (count);
345 }
346 
347 /*
348  * vfscanf(stream,fmt,ap)
349  */
350 static int vfscanf (FILE *stream, const char *fmt, va_list ap)
351 {
352  int count;
353  char buf[MAXLN + 1];
354 
355  if (fgets (buf, MAXLN, stream) == 0) {
356  return (-1);
357  }
358  count = vsscanf (buf, fmt, ap);
359  return (count);
360 }
361 #endif // HAL_OS_FATFS_IO
int printf(const char *fmt,...)
Definition: stdio.c:113
int vasprintf(char **strp, const char *fmt, va_list ap)
Definition: stdio.c:76
static int16_t _atob(uint32_t *vp, char *p, int base)
Definition: stdio.c:172
static char * _getbase(char *p, int *basep)
Definition: stdio.c:148
void * calloc(size_t nmemb, size_t size)
Definition: malloc.c:76
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
Definition: stdio.c:34
int(* vprintf_console_hook)(const char *fmt, va_list arg)
Definition: stdio.c:111
int sscanf(const char *buf, const char *fmt,...)
Definition: stdio.c:136
const char * fmt
Definition: Printf.cpp:14
int vsscanf(const char *buf, const char *s, va_list ap)
float v
Definition: Printf.cpp:15
int scanf(const char *fmt,...)
Definition: stdio.c:127
#define NULL
Definition: hal_types.h:59
int vprintf(const char *fmt, va_list arg)
Definition: stdio.c:100
int16_t atob(uint32_t *vp, char *p, int base)
Definition: stdio.c:227
int snprintf(char *str, size_t size, const char *fmt,...)
Definition: stdio.c:64
float value
int asprintf(char **strp, const char *fmt,...)
Definition: stdio.c:91
char * fgets(char *str, int size, FILE *stream)
get a string from stdin See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:398