0
|
1 /*
|
|
2 soapcpp2_lex.l
|
|
3
|
|
4 Flex/Lex tokenizer.
|
|
5
|
|
6 --------------------------------------------------------------------------------
|
|
7 gSOAP XML Web services tools
|
|
8 Copyright (C) 2000-2013, Robert van Engelen, Genivia Inc. All Rights Reserved.
|
|
9 This part of the software is released under ONE of the following licenses:
|
|
10 GPL or Genivia's license for commercial use.
|
|
11 --------------------------------------------------------------------------------
|
|
12 GPL license.
|
|
13
|
|
14 This program is free software; you can redistribute it and/or modify it under
|
|
15 the terms of the GNU General Public License as published by the Free Software
|
|
16 Foundation; either version 2 of the License, or (at your option) any later
|
|
17 version.
|
|
18
|
|
19 This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
21 PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
22
|
|
23 You should have received a copy of the GNU General Public License along with
|
|
24 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
25 Place, Suite 330, Boston, MA 02111-1307 USA
|
|
26
|
|
27 Author contact information:
|
|
28 engelen@genivia.com / engelen@acm.org
|
|
29
|
|
30 This program is released under the GPL with the additional exemption that
|
|
31 compiling, linking, and/or using OpenSSL is allowed.
|
|
32 --------------------------------------------------------------------------------
|
|
33 A commercial use license is available from Genivia, Inc., contact@genivia.com
|
|
34 --------------------------------------------------------------------------------
|
|
35 */
|
|
36
|
|
37 %{
|
|
38 #include "soapcpp2.h"
|
|
39
|
|
40 #ifdef HAVE_CONFIG_H
|
|
41 #include "soapcpp2_yacc.h"
|
|
42 #else
|
|
43 #include "soapcpp2_yacc.tab.h"
|
|
44 #endif
|
|
45
|
|
46 #ifdef WITH_BISON
|
|
47 YYSTYPE yylval;
|
|
48 #undef YY_INPUT
|
|
49 #define YY_INPUT(buf, result, max_size) \
|
|
50 { \
|
|
51 int c = getc(yyin); \
|
|
52 result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
|
|
53 }
|
|
54 #endif
|
|
55
|
|
56 #ifndef WITH_LEX
|
|
57 #define MAX_IMPORT_DEPTH 16
|
|
58 static struct importlist { struct importlist *next; char name[1]; } *importlist = NULL;
|
|
59 static char fnstk[MAX_IMPORT_DEPTH][1024];
|
|
60 static int lnstk[MAX_IMPORT_DEPTH];
|
|
61 static char *imstk[MAX_IMPORT_DEPTH];
|
|
62 static YY_BUFFER_STATE instk[MAX_IMPORT_DEPTH];
|
|
63 #endif
|
|
64 int imports = 0;
|
|
65 char *imported = NULL;
|
|
66 static void check_id(const char*);
|
|
67 static Token install_id(void);
|
|
68 static Token install_tag(void);
|
|
69 static Token install_int(void);
|
|
70 static Token install_hex(void);
|
|
71 static Token install_num(void);
|
|
72 static Token install_chr(void);
|
|
73 static Token install_str(void);
|
|
74 static Token install_pragma(void);
|
|
75 static void directive(void), option(void);
|
|
76 static Token error_chr(void);
|
|
77 static Token error_str(void);
|
|
78 static int convchar(int*);
|
|
79 static int hexchar(int*);
|
|
80 static int octchar(int*);
|
|
81 static void module(const char *name, const char *fullname);
|
|
82 static void import(const char *file);
|
|
83 static int magic(const char *name);
|
|
84 %}
|
|
85 ws [ \t\v\r\f\n\x1A\xA0]
|
|
86 digit [0-9]
|
|
87 alpha [a-zA-Z_]
|
|
88 id ({alpha}|:{alpha})({alpha}|{digit}|::|:{alpha})*
|
|
89 tag `[^`\t\v\r\f\n>]+`
|
|
90 int {digit}+
|
|
91 hex 0[xX][0-9a-fA-F]+
|
|
92 num {int}(\.{int}([Ee][+-]?{int})?|(\.{int})?[Ee][+-]?{int})
|
|
93 chr '(\\'|[^'\n])*'
|
|
94 str L?\"(\\\"|\\\n|[^"])*\"
|
|
95 module #module{ws}+.*\n
|
|
96 import #import{ws}+.*\n
|
|
97 %x MLCOMMENT
|
|
98 %%
|
|
99 {ws} { /* skip white space */ }
|
|
100 "/*" { BEGIN(MLCOMMENT); }
|
|
101 <MLCOMMENT>.|\n { }
|
|
102 <MLCOMMENT>"*/" { BEGIN(INITIAL); }
|
|
103 <MLCOMMENT><<EOF>> { execerror("Unclosed multiline comment at the end of file"); }
|
|
104 "//"\/*"gsoapopt".*\n { option(); }
|
|
105 "//"\/*"gsoap".*\n { directive(); }
|
|
106 "//".*\n { /* skip single line comment */ }
|
|
107 "+=" { return PA; }
|
|
108 "-=" { return NA; }
|
|
109 "*=" { return TA; }
|
|
110 "/=" { return DA; }
|
|
111 "%=" { return MA; }
|
|
112 "&=" { return AA; }
|
|
113 "^=" { return XA; }
|
|
114 "|=" { return OA; }
|
|
115 "<<=" { return LA; }
|
|
116 ">>=" { return RA; }
|
|
117 "||" { return OR; }
|
|
118 "&&" { return AN; }
|
|
119 "==" { return EQ; }
|
|
120 "!=" { return NE; }
|
|
121 "<=" { return LE; }
|
|
122 ">=" { return GE; }
|
|
123 "<<" { return LS; }
|
|
124 ">>" { return RS; }
|
|
125 "++" { return PP; }
|
|
126 "--" { return NN; }
|
|
127 "->" { return AR; }
|
|
128 [;,:=|^&<>+\-*/%!?~(){}\[\].@$] { return yytext[0]; }
|
|
129 {id} { return install_id(); }
|
|
130 {tag} { return install_tag(); }
|
|
131 {int} { return install_int(); }
|
|
132 {hex} { return install_hex(); }
|
|
133 {num} { return install_num(); }
|
|
134 {chr} { return install_chr(); }
|
|
135 {str} { return install_str(); }
|
|
136 {module} { char *s, *t, buf[1024];
|
|
137 s = strchr(yytext, '"');
|
|
138 if (!s)
|
|
139 t = yytext+7;
|
|
140 else
|
|
141 { strcpy(buf, s+1);
|
|
142 s = strchr(buf, '"');
|
|
143 *s = '\0';
|
|
144 t = strchr(s+1, '"');
|
|
145 if (t)
|
|
146 { t++;
|
|
147 s = strchr(t+1, '"');
|
|
148 if (s)
|
|
149 *s = '\0';
|
|
150 }
|
|
151 }
|
|
152 module(buf, t);
|
|
153 }
|
|
154 {import} { char *s, buf[1024];
|
|
155 s = strchr(yytext, '"');
|
|
156 if (s)
|
|
157 { strcpy(buf, s+1);
|
|
158 s = strchr(buf, '"');
|
|
159 *s = '\0';
|
|
160 import(buf);
|
|
161 }
|
|
162 else
|
|
163 lexerror("Invalid import directive");
|
|
164 }
|
|
165 #.*\n { return install_pragma(); }
|
|
166 '[^'\n]*/\n { return error_chr(); }
|
|
167 \"[^"\n]*/\n { return error_str(); }
|
|
168 . { lexerror("Skipping unknown symbol"); }
|
|
169 <<EOF>> { /* when Lex complains: remove this line and below */
|
|
170 #ifndef WITH_LEX
|
|
171 if (--imports < 0)
|
|
172 yyterminate();
|
|
173 else
|
|
174 { yy_delete_buffer(YY_CURRENT_BUFFER);
|
|
175 yy_switch_to_buffer(instk[imports]);
|
|
176 strcpy(filename, fnstk[imports]);
|
|
177 yylineno = lnstk[imports];
|
|
178 imported = imstk[imports];
|
|
179 }
|
|
180 #endif
|
|
181 }
|
|
182 %%
|
|
183
|
|
184 /*
|
|
185 install_id - lookup identifier in symbol table. If found, return token
|
|
186 and symbol table entry. If not found, create entry in symbol table and
|
|
187 return ID token.
|
|
188 */
|
|
189 static Token
|
|
190 install_id()
|
|
191 { Symbol *p = lookup(yytext);
|
|
192 if (!p)
|
|
193 { int i, flag = 0;
|
|
194 p = install(yytext, ID);
|
|
195 /* [_](x|X)(m|M)(l|L)__ is OK */
|
|
196 /* [_](x|X)(m|M)(l|L).* is not OK */
|
|
197 /* .*__(x|X)(m|M)(l|L) is not OK */
|
|
198 /* .*::(x|X)(m|M)(l|L) is not OK */
|
|
199 for (i = 0; i < yyleng; i++)
|
|
200 { if ((yytext[i] == '_' && yytext[i+1] == '_')
|
|
201 || (yytext[i] == ':' && yytext[i+1] == ':'))
|
|
202 { flag = 1;
|
|
203 check_id(yytext + i + 2);
|
|
204 }
|
|
205 }
|
|
206 if (!flag && strcmp(yytext, "XML"))
|
|
207 check_id(yytext);
|
|
208 }
|
|
209 yylval.sym = p;
|
|
210 return p->token;
|
|
211 }
|
|
212
|
|
213 /*
|
|
214 install_tag -
|
|
215 return TAG token.
|
|
216 */
|
|
217 static Token
|
|
218 install_tag()
|
|
219 { yylval.s = emalloc(yyleng-1); /* yyleng = length(yytext) */
|
|
220 strcpy(yylval.s, yytext+1);
|
|
221 yylval.s[yyleng-2] = '\0';
|
|
222 return TAG;
|
|
223 }
|
|
224
|
|
225 /*
|
|
226 check_id - check for (x|X)(m|M)(l|L)
|
|
227 */
|
|
228 static void
|
|
229 check_id(const char *s)
|
|
230 { while (*s == '_')
|
|
231 s++;
|
|
232 if ((s[0] == 'x' || s[0] == 'X')
|
|
233 && (s[1] == 'm' || s[1] == 'M')
|
|
234 && (s[2] == 'l' || s[2] == 'L'))
|
|
235 { sprintf(errbuf, "identifier '%s' starts with or embeds '%3.3s' character sequence exclusively reserved for the XML standard (for enum constants: please ignore this warning)", yytext, s);
|
|
236 semwarn(errbuf);
|
|
237 }
|
|
238 }
|
|
239
|
|
240 /*
|
|
241 install_int - convert digits to integer and return LNG token.
|
|
242 */
|
|
243 static Token
|
|
244 install_int(void)
|
|
245 {
|
|
246 sscanf(yytext, SOAP_ULONG_FORMAT, &yylval.i);
|
|
247 return LNG;
|
|
248 }
|
|
249
|
|
250 /*
|
|
251 install_hex - convert hexadecimal digits to integer and return LNG
|
|
252 */
|
|
253 static Token
|
|
254 install_hex(void)
|
|
255 {
|
|
256 sscanf(yytext, SOAP_XLONG_FORMAT, &yylval.i);
|
|
257 return LNG;
|
|
258 }
|
|
259
|
|
260 /*
|
|
261 install_num - convert digits to floating point number and return DBL
|
|
262 */
|
|
263 static Token
|
|
264 install_num(void)
|
|
265 { sscanf(yytext, "%lf", &yylval.r);
|
|
266 return DBL;
|
|
267 }
|
|
268
|
|
269 /*
|
|
270 install_chr - convert character constant and return CHR.
|
|
271 */
|
|
272 static Token
|
|
273 install_chr(void)
|
|
274 { int i = 2;
|
|
275 if (yytext[1] == '\\')
|
|
276 yylval.c = convchar(&i);
|
|
277 else yylval.c = yytext[i-1];
|
|
278 if (yytext[i] != '\'')
|
|
279 lexerror("Illegal character constant");
|
|
280 return CHR;
|
|
281 }
|
|
282
|
|
283 /*
|
|
284 install_str - convert and store string in memory. Return STR.
|
|
285 */
|
|
286 static Token
|
|
287 install_str(void)
|
|
288 { int i, j = 0;
|
|
289 yylval.s = emalloc(yyleng-1); /* yyleng = length(yytext) */
|
|
290 for (i = 1 + (yytext[0] == 'L'); i < yyleng-1; i++)
|
|
291 if (yytext[i] == '\\')
|
|
292 { if (yytext[++i] != '\n')
|
|
293 { yylval.s[j++] = convchar(&i);
|
|
294 i--;
|
|
295 }
|
|
296 }
|
|
297 else
|
|
298 yylval.s[j++] = yytext[i];
|
|
299 yylval.s[j] = '\0';
|
|
300 return STR;
|
|
301 }
|
|
302
|
|
303 /*
|
|
304 install_pragma - store pragma in string. Return PRAGMA.
|
|
305 */
|
|
306 static Token
|
|
307 install_pragma(void)
|
|
308 { yylval.s = emalloc(yyleng); /* yyleng = length(yytext) */
|
|
309 strncpy(yylval.s, yytext, strlen(yytext)-1);
|
|
310 yylval.s[strlen(yytext)-1] = '\0';
|
|
311 return PRAGMA;
|
|
312 }
|
|
313
|
|
314 static void directive(void)
|
|
315 { int i, j, k;
|
|
316 char *s;
|
|
317 Service *sp;
|
|
318 Method *m;
|
|
319 Data *d;
|
|
320 int service;
|
|
321 for (i = 7; yytext[i]; i++)
|
|
322 if (yytext[i] > 32)
|
|
323 break;
|
|
324 for (j = i; yytext[j]; j++)
|
|
325 if (yytext[j] <= 32)
|
|
326 break;
|
|
327 if (i == j)
|
|
328 return;
|
|
329 s = (char*)emalloc(j-i+1);
|
|
330 for (k = 0; k < j-i; k++)
|
|
331 { s[k] = yytext[k+i];
|
|
332 if (s[k] == '_')
|
|
333 s[k] = '-';
|
|
334 }
|
|
335 s[k] = '\0';
|
|
336 for (sp = services; sp; sp = sp->next)
|
|
337 if (!strcmp(sp->ns, s))
|
|
338 break;
|
|
339 if (!sp)
|
|
340 { sp = (Service*)emalloc(sizeof(Service));
|
|
341 sp->next = services;
|
|
342 sp->ns = s;
|
|
343 sp->name = NULL;
|
|
344 sp->porttype = NULL;
|
|
345 sp->portname = NULL;
|
|
346 sp->binding = NULL;
|
|
347 sp->definitions = NULL;
|
|
348 sp->transport = NULL;
|
|
349 sp->URL = NULL;
|
|
350 sp->URI = NULL;
|
|
351 sp->URI2 = NULL;
|
|
352 sp->WSDL = NULL;
|
|
353 sp->style = NULL;
|
|
354 sp->encoding = NULL;
|
|
355 sp->protocol = NULL;
|
|
356 sp->xsi_type = 0;
|
|
357 sp->elementForm = NULL;
|
|
358 sp->attributeForm = NULL;
|
|
359 sp->executable = NULL;
|
|
360 sp->import = NULL;
|
|
361 sp->documentation = NULL;
|
|
362 sp->list = NULL;
|
|
363 sp->data = NULL;
|
|
364 services = sp;
|
|
365 }
|
|
366 for (i = j; yytext[i]; i++)
|
|
367 if (yytext[i] > 32)
|
|
368 break;
|
|
369 if (!strncmp(yytext+i, "service", 7) || !strncmp(yytext+i, "schema", 6))
|
|
370 { service = strncmp(yytext+i, "schema", 6);
|
|
371 for (i += 7; yytext[i]; i++)
|
|
372 if (yytext[i] > 32)
|
|
373 break;
|
|
374 for (j = i; yytext[j]; j++)
|
|
375 if (yytext[j] <= 32)
|
|
376 break;
|
|
377 for (; yytext[j]; j++)
|
|
378 if (yytext[j] > 32)
|
|
379 break;
|
|
380 for (k = j; yytext[k]; k++)
|
|
381 if (yytext[k] <= 32)
|
|
382 break;
|
|
383 /*
|
|
384 if (j == k)
|
|
385 return;
|
|
386 */
|
|
387 s = (char*)emalloc(k-j+1);
|
|
388 strncpy(s, yytext+j, k-j);
|
|
389 s[k-j] = '\0';
|
|
390 if (!strncmp(yytext+i, "name:", 5))
|
|
391 { sp->name = s;
|
|
392 for (j = k; yytext[j]; j++)
|
|
393 if (yytext[j] > 32)
|
|
394 break;
|
|
395 for (k = j; yytext[k]; k++)
|
|
396 if (yytext[k] == 10 || yytext[k] == 13)
|
|
397 break;
|
|
398 if (j == k)
|
|
399 return;
|
|
400 s = (char*)emalloc(k-j+1);
|
|
401 strncpy(s, yytext+j, k-j);
|
|
402 s[k-j] = '\0';
|
|
403 sp->documentation = s;
|
|
404 }
|
|
405 else if (!strncmp(yytext+i, "type:", 5) || !strncmp(yytext+i, "portType:", 9) || !strncmp(yytext+i, "interface:", 10))
|
|
406 sp->porttype = s;
|
|
407 else if (!strncmp(yytext+i, "portName:", 9))
|
|
408 sp->portname = s;
|
|
409 else if (!strncmp(yytext+i, "binding:", 8))
|
|
410 sp->binding = s;
|
|
411 else if (!strncmp(yytext+i, "definitions:", 12))
|
|
412 sp->definitions = s;
|
|
413 else if (!strncmp(yytext+i, "documentation:", 14))
|
|
414 { for (k = j; yytext[k]; k++)
|
|
415 if (yytext[k] == 10 || yytext[k] == 13)
|
|
416 break;
|
|
417 if (j == k)
|
|
418 return;
|
|
419 s = (char*)emalloc(k-j+1);
|
|
420 strncpy(s, yytext+j, k-j);
|
|
421 s[k-j] = '\0';
|
|
422 sp->documentation = s;
|
|
423 }
|
|
424 else if (!strncmp(yytext+i, "transport:", 10))
|
|
425 sp->transport = s;
|
|
426 else if (!strncmp(yytext+i, "location:", 9) || !strncmp(yytext+i, "endpoint:", 9) || !strncmp(yytext+i, "port:", 5))
|
|
427 { if (sp->URL)
|
|
428 { char *t = (char*)emalloc(strlen(sp->URL) + strlen(s) + 2);
|
|
429 strcpy(t, sp->URL);
|
|
430 strcat(t, " ");
|
|
431 strcat(t, s);
|
|
432 sp->URL = t;
|
|
433 }
|
|
434 else
|
|
435 sp->URL = s;
|
|
436 if (!service && !sp->import)
|
|
437 sp->import = s;
|
|
438 }
|
|
439 else if (!strncmp(yytext+i, "executable:", 11))
|
|
440 sp->executable = s;
|
|
441 else if (!strncmp(yytext+i, "namespace:", 10))
|
|
442 { if (service)
|
|
443 { if (!sp->URI)
|
|
444 sp->URI = s;
|
|
445 sp->WSDL = s;
|
|
446 }
|
|
447 else if (!strcmp(sp->ns, "SOAP-ENV"))
|
|
448 { if (vflag > 0)
|
|
449 semwarn("option -1 or -2 overrides SOAP-ENV namespace");
|
|
450 else
|
|
451 envURI = s;
|
|
452 sp->URI = envURI;
|
|
453 }
|
|
454 else if (!strcmp(sp->ns, "SOAP-ENC"))
|
|
455 { if (vflag > 0)
|
|
456 semwarn("option -1 or -2 overrides SOAP-ENC namespace");
|
|
457 else
|
|
458 encURI = s;
|
|
459 sp->URI = encURI;
|
|
460 }
|
|
461 else
|
|
462 sp->URI = s;
|
|
463 }
|
|
464 else if (!strncmp(yytext+i, "namespace2:", 11))
|
|
465 { sp->URI2 = s;
|
|
466 }
|
|
467 else if (!strncmp(yytext+i, "typed:", 6))
|
|
468 { sp->xsi_type = (*s == 'y');
|
|
469 }
|
|
470 else if (!strncmp(yytext+i, "form:", 5))
|
|
471 { sp->elementForm = s;
|
|
472 sp->attributeForm = s;
|
|
473 }
|
|
474 else if (!strncmp(yytext+i, "elementForm:", 12))
|
|
475 sp->elementForm = s;
|
|
476 else if (!strncmp(yytext+i, "attributeForm:", 14))
|
|
477 sp->attributeForm = s;
|
|
478 else if (!strncmp(yytext+i, "import:", 7))
|
|
479 { if (!sp->URI)
|
|
480 sp->URI = s;
|
|
481 sp->import = s;
|
|
482 }
|
|
483 else if (!strncmp(yytext+i, "encoding:", 9))
|
|
484 { if (!strcmp(s, "encoded"))
|
|
485 sp->encoding = "";
|
|
486 else
|
|
487 sp->encoding = s;
|
|
488 }
|
|
489 else if (!strncmp(yytext+i, "style:", 6))
|
|
490 sp->style = s;
|
|
491 else if (!strncmp(yytext+i, "protocol:", 9))
|
|
492 sp->protocol = s;
|
|
493 else if (!strncmp(yytext+i, "method-protocol:", 16))
|
|
494 { m = (Method*)emalloc(sizeof(Method));
|
|
495 m->name = s;
|
|
496 m->mess = PROTOCOL;
|
|
497 m->part = NULL;
|
|
498 m->next = sp->list;
|
|
499 sp->list = m;
|
|
500 for (j = k; yytext[j]; j++)
|
|
501 if (yytext[j] > 32)
|
|
502 break;
|
|
503 for (k = j; yytext[k]; k++)
|
|
504 if (yytext[k] == 10 || yytext[k] == 13)
|
|
505 break;
|
|
506 if (j == k)
|
|
507 return;
|
|
508 s = (char*)emalloc(k-j+1);
|
|
509 strncpy(s, yytext+j, k-j);
|
|
510 s[k-j] = '\0';
|
|
511 m->part = s;
|
|
512 }
|
|
513 else if (!strncmp(yytext+i, "method-style:", 13))
|
|
514 { m = (Method*)emalloc(sizeof(Method));
|
|
515 m->name = s;
|
|
516 m->mess = STYLE;
|
|
517 m->part = NULL;
|
|
518 m->next = sp->list;
|
|
519 sp->list = m;
|
|
520 for (j = k; yytext[j]; j++)
|
|
521 if (yytext[j] > 32)
|
|
522 break;
|
|
523 for (k = j; yytext[k]; k++)
|
|
524 if (yytext[k] == 10 || yytext[k] == 13)
|
|
525 break;
|
|
526 if (j == k)
|
|
527 return;
|
|
528 s = (char*)emalloc(k-j+1);
|
|
529 strncpy(s, yytext+j, k-j);
|
|
530 s[k-j] = '\0';
|
|
531 m->part = s;
|
|
532 }
|
|
533 else if (!strncmp(yytext+i, "method-encoding:", 16))
|
|
534 { m = (Method*)emalloc(sizeof(Method));
|
|
535 m->name = s;
|
|
536 m->mess = ENCODING;
|
|
537 m->part = NULL;
|
|
538 m->next = sp->list;
|
|
539 sp->list = m;
|
|
540 for (j = k; yytext[j]; j++)
|
|
541 if (yytext[j] > 32)
|
|
542 break;
|
|
543 for (k = j; yytext[k]; k++)
|
|
544 if (yytext[k] == 10 || yytext[k] == 13)
|
|
545 break;
|
|
546 if (j == k)
|
|
547 return;
|
|
548 s = (char*)emalloc(k-j+1);
|
|
549 strncpy(s, yytext+j, k-j);
|
|
550 s[k-j] = '\0';
|
|
551 if (strcmp(s, "encoded"))
|
|
552 m->part = s;
|
|
553 else
|
|
554 m->part = "";
|
|
555 }
|
|
556 else if (!strncmp(yytext+i, "method-response-encoding:", 25))
|
|
557 { m = (Method*)emalloc(sizeof(Method));
|
|
558 m->name = s;
|
|
559 m->mess = RESPONSE_ENCODING;
|
|
560 m->part = NULL;
|
|
561 m->next = sp->list;
|
|
562 sp->list = m;
|
|
563 for (j = k; yytext[j]; j++)
|
|
564 if (yytext[j] > 32)
|
|
565 break;
|
|
566 for (k = j; yytext[k]; k++)
|
|
567 if (yytext[k] == 10 || yytext[k] == 13)
|
|
568 break;
|
|
569 if (j == k)
|
|
570 return;
|
|
571 s = (char*)emalloc(k-j+1);
|
|
572 strncpy(s, yytext+j, k-j);
|
|
573 s[k-j] = '\0';
|
|
574 if (strcmp(s, "encoded"))
|
|
575 m->part = s;
|
|
576 else
|
|
577 m->part = "";
|
|
578 }
|
|
579 else if (!strncmp(yytext+i, "method-documentation:", 21))
|
|
580 { m = (Method*)emalloc(sizeof(Method));
|
|
581 m->name = s;
|
|
582 m->mess = COMMENT;
|
|
583 m->part = NULL;
|
|
584 m->next = sp->list;
|
|
585 sp->list = m;
|
|
586 for (j = k; yytext[j]; j++)
|
|
587 if (yytext[j] > 32)
|
|
588 break;
|
|
589 for (k = j; yytext[k]; k++)
|
|
590 if (yytext[k] == 10 || yytext[k] == 13)
|
|
591 break;
|
|
592 if (j == k)
|
|
593 return;
|
|
594 s = (char*)emalloc(k-j+1);
|
|
595 strncpy(s, yytext+j, k-j);
|
|
596 s[k-j] = '\0';
|
|
597 m->part = s;
|
|
598 }
|
|
599 else if (!strncmp(yytext+i, "method-action:", 14))
|
|
600 { m = (Method*)emalloc(sizeof(Method));
|
|
601 m->name = s;
|
|
602 m->mess = ACTION;
|
|
603 m->part = NULL;
|
|
604 m->next = sp->list;
|
|
605 sp->list = m;
|
|
606 for (j = k; yytext[j]; j++)
|
|
607 if (yytext[j] > 32)
|
|
608 break;
|
|
609 for (k = j; yytext[k]; k++)
|
|
610 if (yytext[k] == 10 || yytext[k] == 13)
|
|
611 break;
|
|
612 if (j == k)
|
|
613 return;
|
|
614 s = (char*)emalloc(k-j+1);
|
|
615 strncpy(s, yytext+j, k-j);
|
|
616 s[k-j] = '\0';
|
|
617 m->part = s;
|
|
618 }
|
|
619 else if (!strncmp(yytext+i, "method-input-action:", 20))
|
|
620 { m = (Method*)emalloc(sizeof(Method));
|
|
621 m->name = s;
|
|
622 m->mess = REQUEST_ACTION;
|
|
623 m->part = NULL;
|
|
624 m->next = sp->list;
|
|
625 sp->list = m;
|
|
626 for (j = k; yytext[j]; j++)
|
|
627 if (yytext[j] > 32)
|
|
628 break;
|
|
629 for (k = j; yytext[k]; k++)
|
|
630 if (yytext[k] == 10 || yytext[k] == 13)
|
|
631 break;
|
|
632 if (j == k)
|
|
633 return;
|
|
634 s = (char*)emalloc(k-j+1);
|
|
635 strncpy(s, yytext+j, k-j);
|
|
636 s[k-j] = '\0';
|
|
637 m->part = s;
|
|
638 }
|
|
639 else if (!strncmp(yytext+i, "method-output-action:", 21))
|
|
640 { m = (Method*)emalloc(sizeof(Method));
|
|
641 m->name = s;
|
|
642 m->mess = RESPONSE_ACTION;
|
|
643 m->part = NULL;
|
|
644 m->next = sp->list;
|
|
645 sp->list = m;
|
|
646 for (j = k; yytext[j]; j++)
|
|
647 if (yytext[j] > 32)
|
|
648 break;
|
|
649 for (k = j; yytext[k]; k++)
|
|
650 if (yytext[k] == 10 || yytext[k] == 13)
|
|
651 break;
|
|
652 if (j == k)
|
|
653 return;
|
|
654 s = (char*)emalloc(k-j+1);
|
|
655 strncpy(s, yytext+j, k-j);
|
|
656 s[k-j] = '\0';
|
|
657 m->part = s;
|
|
658 }
|
|
659 else if (!strncmp(yytext+i, "method-fault-action:", 20))
|
|
660 { m = (Method*)emalloc(sizeof(Method));
|
|
661 m->name = s;
|
|
662 m->mess = FAULT_ACTION;
|
|
663 m->part = NULL;
|
|
664 m->next = sp->list;
|
|
665 sp->list = m;
|
|
666 for (j = k; yytext[j]; j++)
|
|
667 if (yytext[j] > 32)
|
|
668 break;
|
|
669 for (k = j; yytext[k]; k++)
|
|
670 if (yytext[k] == 10 || yytext[k] == 13)
|
|
671 break;
|
|
672 if (j == k)
|
|
673 return;
|
|
674 s = (char*)emalloc(k-j+1);
|
|
675 strncpy(s, yytext+j, k-j);
|
|
676 s[k-j] = '\0';
|
|
677 m->part = s;
|
|
678 }
|
|
679 else if (!strncmp(yytext+i, "method-mime-type:", 17))
|
|
680 { m = (Method*)emalloc(sizeof(Method));
|
|
681 m->name = s;
|
|
682 m->mess = MIMEIN | MIMEOUT;
|
|
683 m->part = NULL;
|
|
684 m->next = sp->list;
|
|
685 sp->list = m;
|
|
686 for (j = k; yytext[j]; j++)
|
|
687 if (yytext[j] > 32)
|
|
688 break;
|
|
689 for (k = j; yytext[k]; k++)
|
|
690 if (yytext[k] <= 32)
|
|
691 break;
|
|
692 if (j == k)
|
|
693 return;
|
|
694 s = (char*)emalloc(k-j+1);
|
|
695 strncpy(s, yytext+j, k-j);
|
|
696 s[k-j] = '\0';
|
|
697 m->part = s;
|
|
698 }
|
|
699 else if (!strncmp(yytext+i, "method-input-mime-type:", 23))
|
|
700 { m = (Method*)emalloc(sizeof(Method));
|
|
701 m->name = s;
|
|
702 m->mess = MIMEIN;
|
|
703 m->part = NULL;
|
|
704 m->next = sp->list;
|
|
705 sp->list = m;
|
|
706 for (j = k; yytext[j]; j++)
|
|
707 if (yytext[j] > 32)
|
|
708 break;
|
|
709 for (k = j; yytext[k]; k++)
|
|
710 if (yytext[k] <= 32)
|
|
711 break;
|
|
712 if (j == k)
|
|
713 return;
|
|
714 s = (char*)emalloc(k-j+1);
|
|
715 strncpy(s, yytext+j, k-j);
|
|
716 s[k-j] = '\0';
|
|
717 m->part = s;
|
|
718 }
|
|
719 else if (!strncmp(yytext+i, "method-output-mime-type:", 24))
|
|
720 { m = (Method*)emalloc(sizeof(Method));
|
|
721 m->name = s;
|
|
722 m->mess = MIMEOUT;
|
|
723 m->part = NULL;
|
|
724 m->next = sp->list;
|
|
725 sp->list = m;
|
|
726 for (j = k; yytext[j]; j++)
|
|
727 if (yytext[j] > 32)
|
|
728 break;
|
|
729 for (k = j; yytext[k]; k++)
|
|
730 if (yytext[k] <= 32)
|
|
731 break;
|
|
732 if (j == k)
|
|
733 return;
|
|
734 s = (char*)emalloc(k-j+1);
|
|
735 strncpy(s, yytext+j, k-j);
|
|
736 s[k-j] = '\0';
|
|
737 m->part = s;
|
|
738 }
|
|
739 else if (!strncmp(yytext+i, "method-header-part:", 19))
|
|
740 { m = (Method*)emalloc(sizeof(Method));
|
|
741 m->name = s;
|
|
742 m->mess = HDRIN | HDROUT;
|
|
743 m->part = NULL;
|
|
744 m->next = sp->list;
|
|
745 sp->list = m;
|
|
746 for (j = k; yytext[j]; j++)
|
|
747 if (yytext[j] > 32)
|
|
748 break;
|
|
749 for (k = j; yytext[k]; k++)
|
|
750 if (yytext[k] <= 32)
|
|
751 break;
|
|
752 if (j == k)
|
|
753 return;
|
|
754 s = (char*)emalloc(k-j+1);
|
|
755 strncpy(s, yytext+j, k-j);
|
|
756 s[k-j] = '\0';
|
|
757 m->part = s;
|
|
758 }
|
|
759 else if (!strncmp(yytext+i, "method-input-header-part:", 25))
|
|
760 { m = (Method*)emalloc(sizeof(Method));
|
|
761 m->name = s;
|
|
762 m->mess = HDRIN;
|
|
763 m->part = NULL;
|
|
764 m->next = sp->list;
|
|
765 sp->list = m;
|
|
766 for (j = k; yytext[j]; j++)
|
|
767 if (yytext[j] > 32)
|
|
768 break;
|
|
769 for (k = j; yytext[k]; k++)
|
|
770 if (yytext[k] <= 32)
|
|
771 break;
|
|
772 if (j == k)
|
|
773 return;
|
|
774 s = (char*)emalloc(k-j+1);
|
|
775 strncpy(s, yytext+j, k-j);
|
|
776 s[k-j] = '\0';
|
|
777 m->part = s;
|
|
778 }
|
|
779 else if (!strncmp(yytext+i, "method-output-header-part:", 26))
|
|
780 { m = (Method*)emalloc(sizeof(Method));
|
|
781 m->name = s;
|
|
782 m->mess = HDROUT;
|
|
783 m->part = NULL;
|
|
784 m->next = sp->list;
|
|
785 sp->list = m;
|
|
786 for (j = k; yytext[j]; j++)
|
|
787 if (yytext[j] > 32)
|
|
788 break;
|
|
789 for (k = j; yytext[k]; k++)
|
|
790 if (yytext[k] <= 32)
|
|
791 break;
|
|
792 if (j == k)
|
|
793 return;
|
|
794 s = (char*)emalloc(k-j+1);
|
|
795 strncpy(s, yytext+j, k-j);
|
|
796 s[k-j] = '\0';
|
|
797 m->part = s;
|
|
798 }
|
|
799 else if (!strncmp(yytext+i, "method-fault:", 13))
|
|
800 { m = (Method*)emalloc(sizeof(Method));
|
|
801 m->name = s;
|
|
802 m->mess = FAULT;
|
|
803 m->part = NULL;
|
|
804 m->next = sp->list;
|
|
805 sp->list = m;
|
|
806 for (j = k; yytext[j]; j++)
|
|
807 if (yytext[j] > 32)
|
|
808 break;
|
|
809 for (k = j; yytext[k]; k++)
|
|
810 if (yytext[k] <= 32)
|
|
811 break;
|
|
812 if (j == k)
|
|
813 return;
|
|
814 s = (char*)emalloc(k-j+1);
|
|
815 strncpy(s, yytext+j, k-j);
|
|
816 s[k-j] = '\0';
|
|
817 m->part = s;
|
|
818 }
|
|
819 else if (!strncmp(yytext+i, "type-documentation:", 19))
|
|
820 { d = (Data*)emalloc(sizeof(Data));
|
|
821 d->name = s;
|
|
822 d->text = NULL;
|
|
823 d->next = sp->data;
|
|
824 sp->data = d;
|
|
825 for (j = k; yytext[j]; j++)
|
|
826 if (yytext[j] > 32)
|
|
827 break;
|
|
828 for (k = j; yytext[k]; k++)
|
|
829 if (yytext[k] == 10 || yytext[k] == 13)
|
|
830 break;
|
|
831 if (j == k)
|
|
832 return;
|
|
833 s = (char*)emalloc(k-j+1);
|
|
834 strncpy(s, yytext+j, k-j);
|
|
835 s[k-j] = '\0';
|
|
836 d->text = s;
|
|
837 }
|
|
838 else
|
|
839 { sprintf(errbuf, "unrecognized gsoap directive: %s", yytext+i);
|
|
840 semwarn(errbuf);
|
|
841 }
|
|
842 }
|
|
843 else
|
|
844 { sprintf(errbuf, "unrecognized gsoap directive: %s", yytext);
|
|
845 semwarn(errbuf);
|
|
846 }
|
|
847 }
|
|
848
|
|
849 static void option(void)
|
|
850 { int i;
|
|
851 if (imports)
|
|
852 { sprintf(errbuf, "options directive: %s ignored in imported file(s)", yytext);
|
|
853 semwarn(errbuf);
|
|
854 return;
|
|
855 }
|
|
856 for (i = 10; yytext[i]; i++)
|
|
857 if (yytext[i] > 32)
|
|
858 break;
|
|
859 for (; yytext[i]; i++)
|
|
860 switch (yytext[i])
|
|
861 { case 'a':
|
|
862 aflag = 1;
|
|
863 break;
|
|
864 case 'c':
|
|
865 cflag = 1;
|
|
866 break;
|
|
867 case 'e':
|
|
868 eflag = 1;
|
|
869 break;
|
|
870 case 'n':
|
|
871 nflag = 1;
|
|
872 break;
|
|
873 case 'l':
|
|
874 lflag = 1;
|
|
875 break;
|
|
876 case 't':
|
|
877 tflag = 1;
|
|
878 break;
|
|
879 case 'w':
|
|
880 wflag = 1;
|
|
881 break;
|
|
882 default:
|
|
883 if (yytext[i] <= 32)
|
|
884 return;
|
|
885 }
|
|
886 }
|
|
887
|
|
888 /*
|
|
889 error_chr - lexical error in character constant. Return character 0 to
|
|
890 allow parsing to continue
|
|
891 */
|
|
892 static Token
|
|
893 error_chr(void)
|
|
894 { lexerror("Ending-' missing in character constant");
|
|
895 yylval.c = '\0';
|
|
896 return CHR;
|
|
897 }
|
|
898
|
|
899 /*
|
|
900 error_str - lexical error in string. Return empty string to allow
|
|
901 parsing to continue
|
|
902 */
|
|
903 static Token
|
|
904 error_str(void)
|
|
905 { lexerror("Ending-\" missing in string");
|
|
906 yylval.s = "";
|
|
907 return STR;
|
|
908 }
|
|
909
|
|
910 /*
|
|
911 Character conversion functions
|
|
912 */
|
|
913 static int
|
|
914 convchar(int *p)
|
|
915 { switch (yytext[(*p)++])
|
|
916 { case 'a': return '\a';
|
|
917 case 'b': return '\b';
|
|
918 case 'f': return '\f';
|
|
919 case 'n': return '\n';
|
|
920 case 'r': return '\r';
|
|
921 case 't': return '\t';
|
|
922 case 'v': return '\v';
|
|
923 case 'x': return hexchar(p);
|
|
924 case '0':
|
|
925 case '1':
|
|
926 case '2':
|
|
927 case '3':
|
|
928 case '4':
|
|
929 case '5':
|
|
930 case '6':
|
|
931 case '7': (*p)--;
|
|
932 return octchar(p);
|
|
933 default: return yytext[*p-1];
|
|
934 }
|
|
935 }
|
|
936
|
|
937 static int
|
|
938 hexchar(int *p)
|
|
939 { int i, d, c = 0;
|
|
940 for (i = 0; isxdigit(d = yytext[*p]) && i < 2; i++)
|
|
941 { c = (c << 4) + (d <= '9' ? d - '0' : toupper(d) - '7');
|
|
942 (*p)++;
|
|
943 }
|
|
944 return c;
|
|
945 }
|
|
946
|
|
947 static int
|
|
948 octchar(int *p)
|
|
949 { int i, d, c = 0;
|
|
950 for (i = 0; (d = yytext[*p]) >= '0' && d <= '7' && i < 3; i++)
|
|
951 { c = (c << 3) + d - '0';
|
|
952 (*p)++;
|
|
953 }
|
|
954 return c;
|
|
955 }
|
|
956
|
|
957 static void module(const char *name, const char *fullname)
|
|
958 { if (!fullname)
|
|
959 fullname = name;
|
|
960 if (imports)
|
|
961 { Pragma **pp;
|
|
962 char *s = emalloc(strlen(fullname)+15);
|
|
963 sprintf(s, "#include \"%sH.h\"", fullname);
|
|
964 for (pp = &pragmas; *pp; pp = &(*pp)->next)
|
|
965 if (!strcmp((*pp)->pragma, s))
|
|
966 break;
|
|
967 if (!*pp)
|
|
968 { *pp = (Pragma*)emalloc(sizeof(Pragma));
|
|
969 (*pp)->pragma = s;
|
|
970 (*pp)->next = NULL;
|
|
971 }
|
|
972 imported = (char*)emalloc(strlen(fullname)+1);
|
|
973 strcpy(imported, fullname);
|
|
974 fprintf(stderr, "Importing module '%s'\n\n", fullname);
|
|
975 }
|
|
976 else
|
|
977 { lflag = 1;
|
|
978 typeNO = magic(name);
|
|
979 prefix = (char*)emalloc(strlen(fullname)+1);
|
|
980 strcpy(prefix, fullname);
|
|
981 fprintf(stderr, "Compiling module '%s' (magic number = %d)\n\n", fullname, typeNO);
|
|
982 }
|
|
983 }
|
|
984
|
|
985 static int magic(const char *name)
|
|
986 { size_t i;
|
|
987 int n;
|
|
988 if (strlen(name) > 4)
|
|
989 semerror("#module name length must not exceed four characters");
|
|
990 n = 0;
|
|
991 for (i = 0; i < strlen(name); i++)
|
|
992 if (name[i] >= 'a' && name[i] <= 'z')
|
|
993 n = 26*n + name[i] - 'a';
|
|
994 else if (name[i] >= 'A' && name[i] <= 'Z')
|
|
995 n = 26*n + name[i] - 'A';
|
|
996 else
|
|
997 semerror("#module name must be alphabetic and the length must not exceed four characters.\nUse '#module name longname' for longer names.");
|
|
998 return 4699*n + 153424;
|
|
999 }
|
|
1000
|
|
1001 #ifdef WITH_LEX
|
|
1002 static void import(const char *file)
|
|
1003 { execerror("Cannot #import: soapcpp2 not compiled with flex (replace lex with flex)");
|
|
1004 }
|
|
1005 #else
|
|
1006 static void import(const char *file)
|
|
1007 { char buf[1024];
|
|
1008 struct importlist *p;
|
|
1009 for (p = importlist; p; p = p->next)
|
|
1010 if (!strcmp(p->name, file))
|
|
1011 return;
|
|
1012 if (imports >= MAX_IMPORT_DEPTH)
|
|
1013 execerror("Imports nested too deep");
|
|
1014 instk[imports] = YY_CURRENT_BUFFER;
|
|
1015 strcpy(fnstk[imports], filename);
|
|
1016 lnstk[imports] = yylineno;
|
|
1017 imstk[imports] = imported;
|
|
1018 yylineno = 1;
|
|
1019 /* imported = NULL; this is useful to change the semantics of #import to NOT consider non-module imports to be part of the current module */
|
|
1020 imports++;
|
|
1021 if (!(yyin = fopen(file, "r")))
|
|
1022 { if (importpath)
|
|
1023 { char *s, *t;
|
|
1024 s = importpath;
|
|
1025 do
|
|
1026 { size_t n;
|
|
1027 t = strstr(s, SOAP_PATHSEP);
|
|
1028 if (t)
|
|
1029 { if (t - s >= sizeof(buf))
|
|
1030 t = s + sizeof(buf) - 1;
|
|
1031 strncpy(buf, s, t - s);
|
|
1032 buf[t - s] = '\0';
|
|
1033 s = t + sizeof(SOAP_PATHSEP) - 1;
|
|
1034 }
|
|
1035 else
|
|
1036 { strcpy(buf, s);
|
|
1037 s = NULL;
|
|
1038 }
|
|
1039 n = strlen(buf) - 1;
|
|
1040 #ifdef __VMS
|
|
1041 if (buf[n] != ']' && buf[n] != ':')
|
|
1042 strcat(buf, ":");
|
|
1043 #else
|
|
1044 if (buf[n] != SOAP_PATHCAT[0])
|
|
1045 strcat(buf, SOAP_PATHCAT);
|
|
1046 #endif
|
|
1047 strcat(buf, file);
|
|
1048 yyin = fopen(buf, "r");
|
|
1049 }
|
|
1050 while (s && !yyin);
|
|
1051 }
|
|
1052 if (!yyin)
|
|
1053 { sprintf(errbuf, "#import: Cannot open file \"%s\" for reading.\nHint: use option -I<path> (for example -Igsoap/import"SOAP_PATHSEP"gsoap/custom:.)", file);
|
|
1054 execerror(errbuf);
|
|
1055 }
|
|
1056 }
|
|
1057 p = (struct importlist*)malloc(sizeof(struct importlist) + strlen(file)); /* has already + 1 byte size */
|
|
1058 strcpy(p->name, file);
|
|
1059 p->next = importlist;
|
|
1060 importlist = p;
|
|
1061 strcpy(filename, file);
|
|
1062 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
|
1063 }
|
|
1064 #endif
|