"Fossies" - the Fresh Open Source Software Archive 
Member "teapot-2.3.0/scanner.c" (6 Feb 2012, 8207 Bytes) of package /linux/privat/old/teapot-2.3.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "scanner.c" see the
Fossies "Dox" file reference documentation.
1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #ifndef NO_POSIX_SOURCE
3 #undef _POSIX_SOURCE
4 #define _POSIX_SOURCE 1
5 #undef _POSIX_C_SOURCE
6 #define _POSIX_C_SOURCE 2
7 #endif
8
9 #ifdef DMALLOC
10 #include "dmalloc.h"
11 #endif
12
13 #include <assert.h>
14 #include <ctype.h>
15 #include <float.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 extern double strtod(const char *nptr, char **endptr); /* SunOS 4 hack */
20 #include <string.h>
21
22
23 #include "default.h"
24 #include "func.h"
25 #include "main.h"
26 #include "misc.h"
27 #include "scanner.h"
28 /*}}}*/
29
30 /* identcode -- return number of identifier */ /*{{{*/
31 int identcode(const char *s, size_t len)
32 {
33 Tfunc *p;
34 int fident;
35
36 for (p=tfunc,fident=0; p->name[0]!='\0' && (len!=strlen(p->name) || strncmp(s,p->name,len)); ++p,++fident);
37 if (p->name[0]=='\0') return -1;
38 else return fident;
39 }
40 /*}}}*/
41
42 /* charstring -- match quoted string and return token */ /*{{{*/
43 static Token *charstring(const char **s)
44 {
45 const char *r;
46
47 r=*s;
48 if (**s=='"')
49 {
50 ++(*s);
51 while (**s!='\0' && **s!='"') if (**s=='\\' && *((*s)+1)!='\0') (*s)+=2; else ++(*s);
52 if (**s=='\0') { *s=r; return 0; }
53 else
54 {
55 Token *n;
56 char *t;
57
58 ++(*s);
59 n=malloc(sizeof(Token));
60 n->type=STRING;
61 t=n->u.string=malloc((size_t)(*s-r));
62 /* Clean string of quotes. This may waste a few bytes, so? */
63 ++r;
64 while (r<(*s-1)) if (*r=='\\') { *t++=*(r+1); r+=2; } else *t++=*r++;
65 *t='\0';
66 return n;
67 }
68 }
69 else return (Token*)0;
70 }
71 /*}}}*/
72 /* integer -- match an unsigned integer and return token */ /*{{{*/
73 static Token *integer(const char **s)
74 {
75 const char *r;
76 long i;
77
78 r=*s;
79 i=posnumber(r,s);
80 if (*s!=r && **s!='.' && **s!='e')
81 {
82 Token *n;
83
84 n=malloc(sizeof(Token));
85 n->type=INT;
86 n->u.integer=i;
87 return n;
88 }
89 else { *s=r; return (Token*)0; }
90 }
91 /*}}}*/
92 /* flt -- match a floating point number */ /*{{{*/
93 static Token *flt(const char **s)
94 {
95 /* variables */ /*{{{*/
96 const char *t;
97 char *end;
98 Token *n;
99 double x;
100 /*}}}*/
101
102 t=*s;
103 x=strtod(t,&end);
104 *s = end;
105 if (t!=*s && dblfinite(x)==(const char*)0)
106 {
107 n=malloc(sizeof(Token));
108 n->type=FLOAT;
109 n->u.flt=x;
110 return n;
111 }
112 else
113 {
114 *s=t;
115 return (Token*)0;
116 }
117 }
118 /*}}}*/
119 /* op -- match an op and return token */ /*{{{*/
120 static Token *op(const char **s)
121 {
122 Token *n;
123 Operator op;
124
125 switch (**s)
126 {
127 case '+': op=PLUS; break;
128 case '-': op=MINUS; break;
129 case '*': op=MUL; break;
130 case '/': op=DIV; break;
131 case '%': op=MOD; break;
132 case '(': op=OP; break;
133 case ')': op=CP; break;
134 case ',': op=COMMA; break;
135 case '^': op=POW; break;
136 case '<': if (*(*s+1)=='=') { ++(*s); op=LE; } else op=LT; break;
137 case '>': if (*(*s+1)=='=') { ++(*s); op=GE; } else op=GT; break;
138 case '=': if (*(*s+1)=='=') { ++(*s); op=ISEQUAL; } else return (Token*)0; break;
139 case '~': if (*(*s+1)=='=') { ++(*s); op=ABOUTEQ; } else return (Token*)0; break;
140 case '!': if (*(*s+1)=='=') { ++(*s); op=NE; } else return (Token*)0; break;
141 default: return (Token*)0;
142 }
143 n=malloc(sizeof(Token));
144 n->type=OPERATOR;
145 n->u.op=op;
146 ++(*s);
147 return n;
148 }
149 /*}}}*/
150 /* ident -- match an identifier and return token */ /*{{{*/
151 static Token *ident(const char **s)
152 {
153 const char *begin;
154 Token *result;
155
156 if (isalpha((int)**s) || **s=='_' || **s=='@' || **s=='&' || **s=='.' || **s=='$')
157 {
158 int fident;
159
160 begin=*s; ++(*s);
161 while (isalpha((int)**s) || **s=='_' || **s=='@' || **s=='&' || **s=='.' || **s=='$' || isdigit((int)**s)) ++(*s);
162 result=malloc(sizeof(Token));
163 if ((fident=identcode(begin,(size_t)(*s-begin)))==-1)
164 {
165 result->type=LIDENT;
166 result->u.lident=malloc((size_t)(*s-begin+1));
167 (void)strncpy(result->u.lident,begin,(size_t)(*s-begin));
168 result->u.lident[*s-begin]='\0';
169 }
170 else
171 {
172 result->type=FIDENT;
173 result->u.fident=fident;
174 }
175 return result;
176 }
177 return (Token*)0;
178 }
179 /*}}}*/
180
181 /* scan -- scan string into tokens */ /*{{{*/
182 Token **scan(const char **s)
183 {
184 /* variables */ /*{{{*/
185 Token **na,*n;
186 const char *r;
187 int i,j;
188 /*}}}*/
189
190 /* compute number of tokens */ /*{{{*/
191 r=*s;
192 while (*r==' ') ++r;
193 for (i=0; *r!='\0'; ++i)
194 {
195 const char *or;
196
197 or=r;
198 while (*r==' ') ++r;
199 n=charstring(&r);
200 if (n==(Token*)0) n=op(&r);
201 if (n==(Token*)0) n=integer(&r);
202 if (n==(Token*)0) n=flt(&r);
203 if (n==(Token*)0) n=ident(&r);
204 if (or==r) { *s=r; return (Token**)0; }
205 }
206 /*}}}*/
207 /* allocate token space */ /*{{{*/
208 na=malloc(sizeof(Token*)*(i+1));
209 /*}}}*/
210 /* store tokens */ /*{{{*/
211 r=*s;
212 while (*r==' ') ++r;
213 for (j=0; j<i; ++j)
214 {
215 while (*r==' ') ++r;
216 n=charstring(&r);
217 if (n==(Token*)0) n=op(&r);
218 if (n==(Token*)0) n=integer(&r);
219 if (n==(Token*)0) n=flt(&r);
220 if (n==(Token*)0) n=ident(&r);
221 na[j]=n;
222 }
223 na[j]=(Token*)0;
224 /*}}}*/
225 return na;
226 }
227 /*}}}*/
228 /* print -- print token sequence */ /*{{{*/
229 void print(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Token **n)
230 {
231 size_t cur;
232
233 cur=0;
234 if (n!=(Token**)0) for (; cur<size-1 && (*n)!=(Token*)0; ++n) switch ((*n)->type)
235 {
236 /* EMPTY */ /*{{{*/
237 case EMPTY: assert(cur==0); *(s+cur)='\0'; ++cur; break;
238 /*}}}*/
239 /* STRING */ /*{{{*/
240 case STRING:
241 {
242 char *str=(*n)->u.string;
243
244 if (quote)
245 {
246 *(s+cur)='"';
247 ++cur;
248 }
249 while (cur<size && *str!='\0')
250 {
251 if (quote) if (*str=='"' || *str=='\\') *(s+cur++)='\\';
252 if (cur<size) *(s+cur++)=*str;
253 ++str;
254 }
255 if (quote)
256 {
257 if (cur<size) *(s+cur)='"';
258 ++cur;
259 }
260 break;
261 }
262 /*}}}*/
263 /* INT */ /*{{{*/
264 case INT:
265 {
266 char buf[20];
267 size_t buflen;
268
269 buflen=sprintf(buf,"%ld",(*n)->u.integer);
270 assert(buflen<sizeof(buf));
271 (void)strncpy(s+cur,buf,size-cur-1);
272 cur+=buflen;
273 break;
274 }
275 /*}}}*/
276 /* FLOAT */ /*{{{*/
277 case FLOAT:
278 {
279 /* variables */ /*{{{*/
280 char buf[1024],*p;
281 size_t len;
282 /*}}}*/
283
284 len=sprintf(buf,scientific ? "%.*e" : "%.*f",precision==-1 ? DBL_DIG-2 : precision, (*n)->u.flt);
285 assert(len<sizeof(buf));
286 if (!scientific && precision==-1)
287 {
288 p=&buf[len-1];
289 while (p>buf && *p=='0' && *(p-1)!='.') { *p='\0'; --p; --len; }
290 }
291 p=buf+len;
292 while (*--p==' ') { *p='\0'; --len; }
293 (void)strncpy(s+cur,buf,size-cur-1);
294 cur+=len;
295 break;
296 }
297 /*}}}*/
298 /* OPERATOR */ /*{{{*/
299 case OPERATOR:
300 {
301 static const char *ops[]={ "+", "-", "*", "/", "(", ")", ",", "<", "<=", ">=", ">", "==", "~=", "!=", "^", "%" };
302
303 if ((size-cur)>1) *(s+cur++)=*ops[(*n)->u.op];
304 if (*(ops[(*n)->u.op]+1) && (size-cur)>1) *(s+cur++)=*(ops[(*n)->u.op]+1);
305 break;
306 }
307 /*}}}*/
308 /* LIDENT */ /*{{{*/
309 case LIDENT:
310 {
311 size_t identlen;
312
313 identlen=strlen((*n)->u.lident);
314 if ((cur+identlen+1)<=size) strcpy(s+cur,(*n)->u.lident);
315 else (void)strncpy(s+cur,(*n)->u.lident,size-cur-1);
316 cur+=identlen;
317 break;
318 }
319 /*}}}*/
320 /* FIDENT */ /*{{{*/
321 case FIDENT:
322 {
323 size_t identlen;
324
325 identlen=strlen(tfunc[(*n)->u.fident].name);
326 if ((cur+identlen+1)<=size) strcpy(s+cur,tfunc[(*n)->u.fident].name);
327 else (void)strncpy(s+cur,tfunc[(*n)->u.fident].name,size-cur-1);
328 cur+=identlen;
329 break;
330 }
331 /*}}}*/
332 /* LOCATION */ /*{{{*/
333 case LOCATION:
334 {
335 char buf[60];
336
337 sprintf(buf,"&(%d,%d,%d)",(*n)->u.location[0],(*n)->u.location[1],(*n)->u.location[2]);
338 (void)strncpy(s+cur,buf,size-cur-1);
339 cur+=strlen(buf);
340 break;
341 }
342 /*}}}*/
343 /* EEK */ /*{{{*/
344 case EEK:
345 {
346 (void)strncpy(s+cur,_("ERROR"),size-cur-1);
347 cur+=5;
348 break;
349 }
350 /*}}}*/
351 /* default */ /*{{{*/
352 default: assert(0);
353 /*}}}*/
354 }
355 if (cur<size) s[cur] = 0;
356 else s[size-1] = 0;
357 if (chars && mbslen(s) > chars) {
358 for (cur=0; cur < chars; ++cur) s[cur] = '#';
359 s[cur] = 0;
360 }
361 }
362 /*}}}*/