ESP8266 ILI9341 display support code with printf sources, wire-frame viewer and custom fonts  1.0
ESP8266ILI9341DisplayProject
sscanf.c
Go to the documentation of this file.
1 // =============================================
2 // Copyright © 2003 - 2016 Mike Gore, Waterloo, ON N2L 5N4, Canada
3 //
4 // Permission is hereby granted to use this Software for any purpose
5 // including combining with commercial products, creating derivative
6 // works, and redistribution of source or binary code, without
7 // limitation or consideration. Any redistributed copies of this
8 // Software must include the above Copyright Notice.
9 //
10 // THIS SOFTWARE IS PROVIDED "AS IS". THE AUTHOR MAKES NO
11 // WARRANTIES REGARDING THIS SOFTWARE, EXPRESS OR IMPLIED, AS TO ITS
12 // SUITABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
13 // =============================================
14 // History
15 // Written: 2 April 2003 Mike Gore <magore@icr1.uwater.loo.ca>
16 // April 2 - April 8th extesive edits
17 // April 8 Alpha Release
18 // 12 Oct 2016
19 // =============================================
20 // =============================================
21 // Note:!!!!
22 // Use TAB STOPS to 4 or this document will look wrong
23 // =============================================
24 
25 #include "user_config.h"
26 
27 #include <stdint.h>
28 #include <stdarg.h>
29 #include <string.h>
30 #include <math.h>
31 
32 #include "mathio.h"
33 
34 #ifdef SMALL_SSCANF
35 
36 // =============================================
37 //
38 //
39 // WRITTEN by MIKE GORE JUN 1999
40 //
41 // SCANF without multiplies!
42 // Work in progress
43 
44 int sscanf(const char *strp, const char *fmt, ...)
45 {
46  va_list ap;
47  int SIGN = 0;
48  uint8_t SIZE;
49  int args = 0; // Arguments
50  uint8_t width;
51  uint8_t base;
52  uint8_t shift;
53  uint8_t ch;
54  uint8_t spec;
55  unsigned long num;
56 
57  va_start(ap,fmt);
58 
59  while ( (spec = *fmt++) )
60  {
61 
62 
63 // FIXME match all non format spec components with input string HERE
64 // - Of course the format spec includes the width spec, etc
65 // - For now we discard any non % qualified format characters
66 // up to the % character and then the rest of the code eats whats
67 // left in processing the spec later on. In other words we KNOW that
68 // all characters up to a % are unused in the spec itself but really
69 // should be matched with the input to be correct - othersise could cause
70 // parse errors - if present. For now we skip spaces and commas
71 // to avoid the most common issues
72 //
73 
74 //
75 // Skip non format characters - for now
76  if (spec != '%')
77  {
78  if(spec == *strp)
79  ++strp;
80  continue;
81  }
82 
83  // we had a '%'
84  spec = *fmt;
85 
86 
87 // Sync up input string to current argument we want in format spec
88 // Skip white space and commas in input string - for now KLUDGE
89 //
90  while ( (ch = *strp) ) {
91  if(ch == '\t' || ch == ' ' || ch == ',') {
92  ++strp;
93  continue;
94  }
95  break;
96  }
97 
98  width = 0; // Init width
99 
100  while( (spec = *fmt) ) { // spec and fmt point past %
101  if(!(spec >= '0' && spec <= '9'))
102  break;
103  base = width; // width *= 10, base is just a temp here
104  width <<=2;
105  width += base;
106  width <<=1;
107 
108  width += (spec - '0');
109  ++fmt;
110  }
111 
112 // Init numeric control flags in case we have a number to process
113 
114  SIZE = sizeof(int); // Long/Short/Tiny flag, int is default
115  base = 0; // If base gets set below we have a number!
116  shift = 0; // Used for fast multiply
117 
118 // Handle LARGE numbers
119 //
120 
121  if (spec == 'l') { // Large
122  SIZE = sizeof(long);
123  spec = *fmt++;
124  }
125  if (spec == 't') { // tiny
126  SIZE = sizeof(char);
127  spec = *fmt++;
128  }
129 
130 // spec has our format specifier!
131  switch (spec)
132  {
133  case '%':
134  break;
135  case 'c':
136  {
137  unsigned char *c;
138  c = va_arg(ap,unsigned char *);
139  *c = *strp;
140  ++strp;
141  }
142  break;
143  case 's':
144  {
145  unsigned char *p;
146  unsigned char c;
147  p = va_arg(ap,unsigned char *);
148  while (width)
149  {
150  c = *strp;
151  if (!c || c == ' ' || c == '\t')
152  break;
153  *p = c;
154  ++p;
155  ++strp;
156  --width;
157  }
158  *p = 0;
159  }
160  break;
161  case 'B':
162  SIZE = sizeof(long);
163  case 'b':
164  base = 2;
165  shift = 1;
166  break;
167  case 'O':
168  SIZE = sizeof(long);
169  case 'o':
170  base = 8;
171  shift = 3;
172  break;
173  case 'X':
174  SIZE = sizeof(long);
175  case 'x':
176  base = 16;
177  shift = 4;
178  break;
179  case 'U':
180  case 'D':
181  SIZE = sizeof(long);
182  case 'u':
183  case 'd':
184  base = 10;
185 //printf("sscanf: sizeof(long) = %d\n", sizeof(long));
186 //printf("sscanf: sizeof(int) = %d\n", sizeof(int));
187 //printf("sscanf: size = %d, base = %d\n", (int)SIZE, (int)base);
188 //printf("sscanf strp:%s\n", strp);
189  break;
190  case 'f':
191  SIZE = sizeof(double);
192  break;
193  default:
194  break;
195  }
196 // IF base is non zero we have some kind of number to process
197 
198  if(base) {
199  num = 0;
200  SIGN = 0;
201  if (!width)
202  width = strlen(strp);
203 
204  ch = *strp;
205  if (ch == '-')
206  {
207  SIGN = 1;
208  ++strp;
209  }
210  else if(ch == '+')
211  {
212  ++strp;
213  }
214 
215  while (width && (ch = *strp)) {
216  if (ch < '0')
217  break;
218 
219  if (ch >= 'a')
220  ch -= ('a' - 10);
221  else if (ch >= 'A')
222  ch -= ('A' - 10);
223  else
224  ch -= '0';
225 
226  if (ch >= base)
227  break;
228 
229  if(base == 10) {
230  unsigned long temp;
231  num <<= 1;
232  temp = num;
233  num <<= 2;
234  num += temp;
235  }
236  else {
237  num <<= shift;
238  }
239  num += ch;
240  ++strp;
241  --width;
242 //printf("sscanf: %ld\n",num);
243  } // END WHILE
244  if(SIZE == sizeof(long)) {
245  unsigned long *c;
246  c = va_arg(ap,unsigned long *);
247  if(SIGN)
248  *c = (unsigned long) -num;
249  else
250  *c = (unsigned long) num;
251  }
252  else if(SIZE == sizeof(int)) {
253  unsigned int *c;
254  c = va_arg(ap,unsigned int *);
255  if(SIGN)
256  *c = (unsigned int) -num;
257  else
258  *c = (unsigned int) num;
259  }
260  else {
261  unsigned char *c;
262  c = va_arg(ap,uint8_t *);
263  if(SIGN)
264  *c = (unsigned char) -num;
265  else
266  *c = (unsigned char) num;
267  }
268  } // END IF(base && width)
269  else if(SIZE = sizeof(double))
270  {
271  // FIXME width
272  double *d = va_arg(ap,double *);
273  char *ptr,*endp;
274  int len = strlen(strp);
275  if(!width)
276  width = len;
277  if(width > len)
278  width = len;
279  ptr = stralloc((char *)strp);
280  *d = strtod(ptr, &endp);
281  free(ptr);
282  strp += (endp - ptr);
283  }
284  ++args;
285  } // END WHILE
286  return (args);
287 }
288 
289 #endif // ifdef SMALL_SSCANF
MEMSPACE size_t WEAK_ATR strlen(const char *str)
String Length.
Definition: stringsup.c:146
Master include file for project Includes all project includes and defines here.
MEMSPACE double strtod(const char *nptr, char **endptr)
MEMSPACE void free(void *p)
Free buffer POSIX function We only call os_free() is pointer is not null.
Definition: system.c:87
Math IO functions, and verious conversion code with floating point support.
int sscanf(const char *strp, const char *fmt,...)
MEMSPACE char * stralloc(char *str)
Allocate space for string.
Definition: stringsup.c:774
unsigned char uint8_t
Definition: send.c:17