7
gSOAP XML Web services tools
8
Copyright (C) 2004, Robert van Engelen, Genivia, Inc. All Rights Reserved.
10
--------------------------------------------------------------------------------
13
The contents of this file are subject to the gSOAP Public License Version 1.3
14
(the "License"); you may not use this file except in compliance with the
15
License. You may obtain a copy of the License at
16
http://www.cs.fsu.edu/~engelen/soaplicense.html
17
Software distributed under the License is distributed on an "AS IS" basis,
18
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19
for the specific language governing rights and limitations under the License.
21
The Initial Developer of the Original Code is Robert A. van Engelen.
22
Copyright (C) 2000-2004 Robert A. van Engelen, Genivia inc. All Rights Reserved.
23
--------------------------------------------------------------------------------
26
This program is free software; you can redistribute it and/or modify it under
27
the terms of the GNU General Public License as published by the Free Software
28
Foundation; either version 2 of the License, or (at your option) any later
31
This program is distributed in the hope that it will be useful, but WITHOUT ANY
32
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
33
PARTICULAR PURPOSE. See the GNU General Public License for more details.
35
You should have received a copy of the GNU General Public License along with
36
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
37
Place, Suite 330, Boston, MA 02111-1307 USA
39
Author contact information:
40
engelen@genivia.com / engelen@acm.org
41
--------------------------------------------------------------------------------
46
#include "soapcpp2_yacc.h"
50
#define YY_INPUT(buf, result, max_size) \
53
result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
58
#define MAX_IMPORT_DEPTH 16
59
static struct imported { struct imported *next; char name[1]; } *imported = NULL;
60
static char fnstk[MAX_IMPORT_DEPTH][1024];
61
static int lnstk[MAX_IMPORT_DEPTH];
62
static YY_BUFFER_STATE instk[MAX_IMPORT_DEPTH];
65
static Token install_id();
66
static Token install_int();
67
static Token install_hex();
68
static Token install_num();
69
static Token install_chr();
70
static Token install_str();
71
static Token install_pragma();
72
static void directive(), option();
73
static Token error_chr();
74
static Token error_str();
75
static int convchar(int*);
76
static int hexchar(int*);
77
static int octchar(int*);
78
static void module(const char *name), import(const char *file);
79
static void endimport();
80
static int magic(const char *name);
85
id {alpha}({alpha}|{digit}|{scope})*
88
num {int}(\.{int}([Ee][+-]?{int})?|(\.{int})?[Ee][+-]?{int})
90
str \"(\\\"|\\\n|[^"])*\"
91
module #module[ \t]*{str}.*\n
92
import #import[ \t]*{str}.*\n
96
[ \t\v\n\f\r\x1A\xA0] { /* skip white space (\x1A is ^Z and \xA0 is HTML non-breakable space) */ }
97
"/*" { BEGIN(MLCOMMENT); }
98
<MLCOMMENT>[^*] { /* eat anything that's not a '*' */ }
99
<MLCOMMENT>"*"[^/] { /* eat up '*'s not followed by '/'s */ }
100
<MLCOMMENT>"*/" { BEGIN(INITIAL); }
101
<MLCOMMENT><<EOF>> { execerror("Unclosed multiline comment at the end of file"); }
102
"//gsoapopt".*\n { option(); }
103
"//gsoap".*\n { directive(); }
104
"//".*\n { /* skip single line comment */ }
126
[;,:=|^&<>+\-*/%!?~(){}\[\].@] { return yytext[0]; }
127
{id} { return install_id(); }
128
{int} { return install_int(); }
129
{hex} { return install_hex(); }
130
{num} { return install_num(); }
131
{chr} { return install_chr(); }
132
{str} { return install_str(); }
133
{module} { char *s, buf[1024];
134
s = strchr(yytext, '"');
136
s = strchr(buf, '"');
140
{import} { char *s, buf[1024];
141
s = strchr(yytext, '"');
143
s = strchr(buf, '"');
147
#.*\n { return install_pragma(); }
148
'[^'\n]*/\n { return error_chr(); }
149
\"[^"\n]*/\n { return error_str(); }
150
. { lexerror("Skipping unknown symbol"); }
151
{eof} { /* in case Lex complains, remove this line */
156
{ yy_delete_buffer(YY_CURRENT_BUFFER);
157
yy_switch_to_buffer(instk[imports]);
158
strcpy(filename, fnstk[imports]);
159
yylineno = lnstk[imports];
166
install_id - lookup identifier in symbol table. If found, return token
167
and symbol table entry. If not found, create entry in symbol table and
172
{ Symbol *p = lookup(yytext);
174
p = install(yytext, ID);
180
install_int - convert digits to integer and return LNG token.
186
sscanf(yytext, "%I64u", &yylval.i);
188
sscanf(yytext, "%llu", &yylval.i);
194
install_hex - convert hexadecimal digits to integer and return LNG
200
sscanf(yytext, "%I64x", &yylval.i);
202
sscanf(yytext, "%llx", &yylval.i);
208
install_num - convert digits to floating point number and return DBL
212
{ sscanf(yytext, "%lf", &yylval.r);
217
install_chr - convert character constant and return CHR.
222
if (yytext[1] == '\\')
223
yylval.c = convchar(&i);
224
else yylval.c = yytext[i-1];
225
if (yytext[i] != '\'')
226
lexerror("Illegal character constant");
231
install_str - convert and store string in memory. Return STR.
236
yylval.s = emalloc(yyleng-1); /* yyleng = length(yytext) */
237
for (i = 1; i < yyleng-1; i++)
238
if (yytext[i] == '\\')
239
{ if (yytext[++i] != '\n')
240
{ yylval.s[j++] = convchar(&i);
245
yylval.s[j++] = yytext[i];
251
install_pragma - store pragma in string. Return PRAGMA.
255
{ yylval.s = emalloc(yyleng); /* yyleng = length(yytext) */
256
strncpy(yylval.s, yytext, strlen(yytext)-1);
257
yylval.s[strlen(yytext)-1] = '\0';
261
static void directive()
267
for (i = 7; yytext[i]; i++)
270
for (j = i; yytext[j]; j++)
275
s = (char*)emalloc(j-i+1);
276
strncpy(s, yytext+i, j-i);
278
for (sp = services; sp; sp = sp->next)
279
if (!strcmp(sp->ns, s))
282
{ sp = (Service*)emalloc(sizeof(Service));
292
sp->elementForm = NULL;
293
sp->attributeForm = NULL;
294
sp->executable = NULL;
296
sp->documentation = NULL;
300
for (i = j; yytext[i]; i++)
303
if (!strncmp(yytext+i, "service", 7) || !strncmp(yytext+i, "schema", 6))
304
{ service = strncmp(yytext+i, "schema", 6);
305
for (i += 7; yytext[i]; i++)
308
for (j = i; yytext[j]; j++)
311
for (; yytext[j]; j++)
314
for (k = j; yytext[k]; k++)
319
s = (char*)emalloc(k-j+1);
320
strncpy(s, yytext+j, k-j);
322
if (!strncmp(yytext+i, "name:", 5))
324
for (j = k; yytext[j]; j++)
327
for (k = j; yytext[k]; k++)
328
if (yytext[k] == 10 || yytext[k] == 13)
332
s = (char*)emalloc(k-j+1);
333
strncpy(s, yytext+j, k-j);
335
sp->documentation = s;
337
else if (!strncmp(yytext+i, "type:", 5))
339
else if (!strncmp(yytext+i, "portType:", 9))
341
else if (!strncmp(yytext+i, "documentation:", 14))
342
{ for (k = j; yytext[k]; k++)
343
if (yytext[k] == 10 || yytext[k] == 13)
347
s = (char*)emalloc(k-j+1);
348
strncpy(s, yytext+j, k-j);
350
sp->documentation = s;
352
else if (!strncmp(yytext+i, "location:", 9) || !strncmp(yytext+i, "port:", 5))
354
else if (!strncmp(yytext+i, "executable:", 11))
356
else if (!strncmp(yytext+i, "namespace:", 10))
362
else if (vflag != 0 && !strcmp(sp->ns, "SOAP-ENV"))
364
else if (vflag != 0 && !strcmp(sp->ns, "SOAP-ENC"))
369
else if (!strncmp(yytext+i, "form:", 5))
370
{ sp->elementForm = s;
371
sp->attributeForm = s;
373
else if (!strncmp(yytext+i, "elementForm:", 12))
375
else if (!strncmp(yytext+i, "attributeForm:", 14))
376
sp->attributeForm = s;
377
else if (!strncmp(yytext+i, "import:", 7))
382
else if (!strncmp(yytext+i, "encoding:", 9))
383
{ if (!strcmp(s, "encoded"))
388
else if (!strncmp(yytext+i, "style:", 6))
390
else if (!strncmp(yytext+i, "method-style:", 13))
391
{ m = (Method*)emalloc(sizeof(Method));
397
for (j = k; yytext[j]; j++)
400
for (k = j; yytext[k]; k++)
401
if (yytext[k] == 10 || yytext[k] == 13)
405
s = (char*)emalloc(k-j+1);
406
strncpy(s, yytext+j, k-j);
410
else if (!strncmp(yytext+i, "method-encoding:", 16))
411
{ m = (Method*)emalloc(sizeof(Method));
417
for (j = k; yytext[j]; j++)
420
for (k = j; yytext[k]; k++)
421
if (yytext[k] == 10 || yytext[k] == 13)
425
s = (char*)emalloc(k-j+1);
426
strncpy(s, yytext+j, k-j);
428
if (strcmp(s, "encoded"))
433
else if (!strncmp(yytext+i, "method-response-encoding:", 25))
434
{ m = (Method*)emalloc(sizeof(Method));
436
m->mess = RESPONSE_ENCODING;
440
for (j = k; yytext[j]; j++)
443
for (k = j; yytext[k]; k++)
444
if (yytext[k] == 10 || yytext[k] == 13)
448
s = (char*)emalloc(k-j+1);
449
strncpy(s, yytext+j, k-j);
451
if (strcmp(s, "encoded"))
456
else if (!strncmp(yytext+i, "method-documentation:", 21))
457
{ m = (Method*)emalloc(sizeof(Method));
463
for (j = k; yytext[j]; j++)
466
for (k = j; yytext[k]; k++)
467
if (yytext[k] == 10 || yytext[k] == 13)
471
s = (char*)emalloc(k-j+1);
472
strncpy(s, yytext+j, k-j);
476
else if (!strncmp(yytext+i, "method-action:", 14))
477
{ m = (Method*)emalloc(sizeof(Method));
483
for (j = k; yytext[j]; j++)
486
for (k = j; yytext[k]; k++)
491
s = (char*)emalloc(k-j+1);
492
strncpy(s, yytext+j, k-j);
496
else if (!strncmp(yytext+i, "method-header-part:", 19))
497
{ m = (Method*)emalloc(sizeof(Method));
499
m->mess = HDRIN | HDROUT;
503
for (j = k; yytext[j]; j++)
506
for (k = j; yytext[k]; k++)
511
s = (char*)emalloc(k-j+1);
512
strncpy(s, yytext+j, k-j);
516
else if (!strncmp(yytext+i, "method-input-header-part:", 25))
517
{ m = (Method*)emalloc(sizeof(Method));
523
for (j = k; yytext[j]; j++)
526
for (k = j; yytext[k]; k++)
531
s = (char*)emalloc(k-j+1);
532
strncpy(s, yytext+j, k-j);
536
else if (!strncmp(yytext+i, "method-output-header-part:", 26))
537
{ m = (Method*)emalloc(sizeof(Method));
543
for (j = k; yytext[j]; j++)
546
for (k = j; yytext[k]; k++)
551
s = (char*)emalloc(k-j+1);
552
strncpy(s, yytext+j, k-j);
556
else if (!strncmp(yytext+i, "method-fault:", 13))
557
{ m = (Method*)emalloc(sizeof(Method));
563
for (j = k; yytext[j]; j++)
566
for (k = j; yytext[k]; k++)
571
s = (char*)emalloc(k-j+1);
572
strncpy(s, yytext+j, k-j);
577
{ sprintf(errbuf, "unrecognized gsoap directive: '%s'", yytext+i);
582
{ sprintf(errbuf, "unrecognized gsoap directive: '%s'", yytext);
589
for (i = 10; yytext[i]; i++)
592
for (; yytext[i]; i++)
616
error_chr - lexical error in character constant. Return character 0 to
617
allow parsing to continue
621
{ lexerror("Ending-' missing in character constant");
627
error_str - lexical error in string. Return empty string to allow
632
{ lexerror("Ending-\" missing in string");
638
Character conversion functions
642
{ switch (yytext[(*p)++])
643
{ case 'a': return '\a';
644
case 'b': return '\b';
645
case 'f': return '\f';
646
case 'n': return '\n';
647
case 'r': return '\r';
648
case 't': return '\t';
649
case 'v': return '\v';
650
case 'x': return hexchar(p);
660
default: return yytext[*p-1];
667
for (i = 0; isxdigit(d = yytext[*p]) && i < 2; i++)
668
{ c = (c << 4) + (d <= '9' ? d - '0' : toupper(d) - '7');
677
for (i = 0; (d = yytext[*p]) >= '0' && d <= '7' && i < 3; i++)
678
{ c = (c << 3) + d - '0';
684
static void module(const char *name)
688
char *s = emalloc(256);
689
sprintf(s, "#include \"%sH.h\"", name);
690
for (pp = &pragmas; *pp; pp = &(*pp)->next)
692
*pp = (Pragma*)emalloc(sizeof(Pragma));
696
fprintf(stderr, "Importing module %s\n", name);
701
typeNO = magic(name);
702
prefix = emalloc(strlen(name)+1);
703
strcpy(prefix, name);
704
fprintf(stderr, "Module %s\n", name);
708
static int magic(const char *name)
710
if (strlen(name) > 4)
711
semerror("#module name length must not exceed four characters");
713
for (i = 0; i < strlen(name); i++)
714
if (name[i] >= 'a' && name[i] <= 'z')
715
n = 26*n + name[i] - 'a';
716
else if (name[i] >= 'A' && name[i] <= 'Z')
717
n = 26*n + name[i] - 'A';
719
semerror("#module name must be alphabetic and the length must not exceed four characters");
720
return 4699*n + 153424;
724
static void import(const char *file)
725
{ execerror("Cannot #import: soapcpp2 not compiled with flex");
728
static void import(const char *file)
731
for (p = imported; p; p = p->next)
732
if (!strcmp(p->name, file))
734
if (imports >= MAX_IMPORT_DEPTH)
735
execerror("Imports nested too deeply");
736
instk[imports] = YY_CURRENT_BUFFER;
737
strcpy(fnstk[imports], filename);
738
lnstk[imports] = yylineno;
740
if (!(yyin = fopen(file, "r")))
742
{ strcpy(buf, importpath);
745
yyin = fopen(buf, "r");
748
{ sprintf(errbuf, "#import: Cannot open file \"%s\" for reading", file);
752
p = (struct imported*)malloc(sizeof(struct imported) + strlen(file));
753
strcpy(p->name, file);
756
strcpy(filename, file);
757
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));