7
gSOAP XML Web services tools
8
Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc. All Rights Reserved.
9
This part of the software is released under one of the following licenses:
10
GPL, the gSOAP public license, or Genivia's license for commercial use.
11
--------------------------------------------------------------------------------
14
The contents of this file are subject to the gSOAP Public License Version 1.3
15
(the "License"); you may not use this file except in compliance with the
16
License. You may obtain a copy of the License at
17
http://www.cs.fsu.edu/~engelen/soaplicense.html
18
Software distributed under the License is distributed on an "AS IS" basis,
19
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20
for the specific language governing rights and limitations under the License.
22
The Initial Developer of the Original Code is Robert A. van Engelen.
23
Copyright (C) 2000-2007 Robert A. van Engelen, Genivia inc. All Rights Reserved.
24
--------------------------------------------------------------------------------
27
This program is free software; you can redistribute it and/or modify it under
28
the terms of the GNU General Public License as published by the Free Software
29
Foundation; either version 2 of the License, or (at your option) any later
32
This program is distributed in the hope that it will be useful, but WITHOUT ANY
33
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
34
PARTICULAR PURPOSE. See the GNU General Public License for more details.
36
You should have received a copy of the GNU General Public License along with
37
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
38
Place, Suite 330, Boston, MA 02111-1307 USA
40
Author contact information:
41
engelen@genivia.com / engelen@acm.org
42
--------------------------------------------------------------------------------
43
A commercial use license is available from Genivia, Inc., contact@genivia.com
44
--------------------------------------------------------------------------------
51
#include "soapcpp2_yacc.h"
53
#include "soapcpp2_yacc.tab.h"
59
#define YY_INPUT(buf, result, max_size) \
62
result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
67
#define MAX_IMPORT_DEPTH 16
68
static struct importlist { struct importlist *next; char name[1]; } *importlist = NULL;
69
static char fnstk[MAX_IMPORT_DEPTH][1024];
70
static int lnstk[MAX_IMPORT_DEPTH];
71
static char *imstk[MAX_IMPORT_DEPTH];
72
static YY_BUFFER_STATE instk[MAX_IMPORT_DEPTH];
75
char *imported = NULL;
76
static Token install_id();
77
static Token install_int();
78
static Token install_hex();
79
static Token install_num();
80
static Token install_chr();
81
static Token install_str();
82
static Token install_pragma();
83
static void directive(), option();
84
static Token error_chr();
85
static Token error_str();
86
static int convchar(int*);
87
static int hexchar(int*);
88
static int octchar(int*);
89
static void module(const char *name, const char *fullname);
90
static void import(const char *file);
91
static int magic(const char *name);
93
ws [ \t\v\n\f\r\x1A\xA0]
96
id {alpha}({alpha}|{digit}|::|:{alpha})*
99
num {int}(\.{int}([Ee][+-]?{int})?|(\.{int})?[Ee][+-]?{int})
101
str \"(\\\"|\\\n|[^"])*\"
102
module #module{ws}+.*\n
103
import #import{ws}+.*\n
106
{ws} { /* skip white space */ }
107
"/*" { BEGIN(MLCOMMENT); }
109
<MLCOMMENT>"*/" { BEGIN(INITIAL); }
110
<MLCOMMENT><<EOF>> { execerror("Unclosed multiline comment at the end of file"); }
111
"//gsoapopt".*\n { option(); }
112
"//gsoap".*\n { directive(); }
113
"//".*\n { /* skip single line comment */ }
135
[;,:=|^&<>+\-*/%!?~(){}\[\].@] { return yytext[0]; }
136
{id} { return install_id(); }
137
{int} { return install_int(); }
138
{hex} { return install_hex(); }
139
{num} { return install_num(); }
140
{chr} { return install_chr(); }
141
{str} { return install_str(); }
142
{module} { char *s, *t, buf[1024];
143
s = strchr(yytext, '"');
145
s = strchr(buf, '"');
147
t = strchr(s+1, '"');
150
s = strchr(t+1, '"');
155
{import} { char *s, buf[1024];
156
s = strchr(yytext, '"');
158
s = strchr(buf, '"');
162
#.*\n { return install_pragma(); }
163
'[^'\n]*/\n { return error_chr(); }
164
\"[^"\n]*/\n { return error_str(); }
165
. { lexerror("Skipping unknown symbol"); }
166
<<EOF>> { /* when Lex complains: remove this line and below */
171
{ yy_delete_buffer(YY_CURRENT_BUFFER);
172
yy_switch_to_buffer(instk[imports]);
173
strcpy(filename, fnstk[imports]);
174
yylineno = lnstk[imports];
175
imported = imstk[imports];
182
install_id - lookup identifier in symbol table. If found, return token
183
and symbol table entry. If not found, create entry in symbol table and
188
{ Symbol *p = lookup(yytext);
190
p = install(yytext, ID);
196
install_int - convert digits to integer and return LNG token.
201
sscanf(yytext, SOAP_ULONG_FORMAT, &yylval.i);
206
install_hex - convert hexadecimal digits to integer and return LNG
211
sscanf(yytext, SOAP_XLONG_FORMAT, &yylval.i);
216
install_num - convert digits to floating point number and return DBL
220
{ sscanf(yytext, "%lf", &yylval.r);
225
install_chr - convert character constant and return CHR.
230
if (yytext[1] == '\\')
231
yylval.c = convchar(&i);
232
else yylval.c = yytext[i-1];
233
if (yytext[i] != '\'')
234
lexerror("Illegal character constant");
239
install_str - convert and store string in memory. Return STR.
244
yylval.s = emalloc(yyleng-1); /* yyleng = length(yytext) */
245
for (i = 1; i < yyleng-1; i++)
246
if (yytext[i] == '\\')
247
{ if (yytext[++i] != '\n')
248
{ yylval.s[j++] = convchar(&i);
253
yylval.s[j++] = yytext[i];
259
install_pragma - store pragma in string. Return PRAGMA.
263
{ yylval.s = emalloc(yyleng); /* yyleng = length(yytext) */
264
strncpy(yylval.s, yytext, strlen(yytext)-1);
265
yylval.s[strlen(yytext)-1] = '\0';
269
static void directive()
276
for (i = 7; yytext[i]; i++)
279
for (j = i; yytext[j]; j++)
284
s = (char*)emalloc(j-i+1);
285
for (k = 0; k < j-i; k++)
286
{ s[k] = yytext[k+i];
291
for (sp = services; sp; sp = sp->next)
292
if (!strcmp(sp->ns, s))
295
{ sp = (Service*)emalloc(sizeof(Service));
302
sp->definitions = NULL;
303
sp->transport = NULL;
309
sp->elementForm = NULL;
310
sp->attributeForm = NULL;
311
sp->executable = NULL;
313
sp->documentation = NULL;
318
for (i = j; yytext[i]; i++)
321
if (!strncmp(yytext+i, "service", 7) || !strncmp(yytext+i, "schema", 6))
322
{ service = strncmp(yytext+i, "schema", 6);
323
for (i += 7; yytext[i]; i++)
326
for (j = i; yytext[j]; j++)
329
for (; yytext[j]; j++)
332
for (k = j; yytext[k]; k++)
339
s = (char*)emalloc(k-j+1);
340
strncpy(s, yytext+j, k-j);
342
if (!strncmp(yytext+i, "name:", 5))
344
for (j = k; yytext[j]; j++)
347
for (k = j; yytext[k]; k++)
348
if (yytext[k] == 10 || yytext[k] == 13)
352
s = (char*)emalloc(k-j+1);
353
strncpy(s, yytext+j, k-j);
355
sp->documentation = s;
357
else if (!strncmp(yytext+i, "type:", 5))
359
else if (!strncmp(yytext+i, "portType:", 9))
361
else if (!strncmp(yytext+i, "portName:", 9))
363
else if (!strncmp(yytext+i, "binding:", 8))
365
else if (!strncmp(yytext+i, "definitions:", 12))
367
else if (!strncmp(yytext+i, "documentation:", 14))
368
{ for (k = j; yytext[k]; k++)
369
if (yytext[k] == 10 || yytext[k] == 13)
373
s = (char*)emalloc(k-j+1);
374
strncpy(s, yytext+j, k-j);
376
sp->documentation = s;
378
else if (!strncmp(yytext+i, "transport:", 10))
380
else if (!strncmp(yytext+i, "location:", 9) || !strncmp(yytext+i, "port:", 5))
385
else if (!strncmp(yytext+i, "executable:", 11))
387
else if (!strncmp(yytext+i, "namespace:", 10))
393
else if (!strcmp(sp->ns, "SOAP-ENV"))
394
sp->URI = envURI = s;
395
else if (!strcmp(sp->ns, "SOAP-ENC"))
396
sp->URI = encURI = s;
400
else if (!strncmp(yytext+i, "form:", 5))
401
{ sp->elementForm = s;
402
sp->attributeForm = s;
404
else if (!strncmp(yytext+i, "elementForm:", 12))
406
else if (!strncmp(yytext+i, "attributeForm:", 14))
407
sp->attributeForm = s;
408
else if (!strncmp(yytext+i, "import:", 7))
413
else if (!strncmp(yytext+i, "encoding:", 9))
414
{ if (!strcmp(s, "encoded"))
419
else if (!strncmp(yytext+i, "style:", 6))
421
else if (!strncmp(yytext+i, "method-style:", 13))
422
{ m = (Method*)emalloc(sizeof(Method));
428
for (j = k; yytext[j]; j++)
431
for (k = j; yytext[k]; k++)
432
if (yytext[k] == 10 || yytext[k] == 13)
436
s = (char*)emalloc(k-j+1);
437
strncpy(s, yytext+j, k-j);
441
else if (!strncmp(yytext+i, "method-encoding:", 16))
442
{ m = (Method*)emalloc(sizeof(Method));
448
for (j = k; yytext[j]; j++)
451
for (k = j; yytext[k]; k++)
452
if (yytext[k] == 10 || yytext[k] == 13)
456
s = (char*)emalloc(k-j+1);
457
strncpy(s, yytext+j, k-j);
459
if (strcmp(s, "encoded"))
464
else if (!strncmp(yytext+i, "method-response-encoding:", 25))
465
{ m = (Method*)emalloc(sizeof(Method));
467
m->mess = RESPONSE_ENCODING;
471
for (j = k; yytext[j]; j++)
474
for (k = j; yytext[k]; k++)
475
if (yytext[k] == 10 || yytext[k] == 13)
479
s = (char*)emalloc(k-j+1);
480
strncpy(s, yytext+j, k-j);
482
if (strcmp(s, "encoded"))
487
else if (!strncmp(yytext+i, "method-documentation:", 21))
488
{ m = (Method*)emalloc(sizeof(Method));
494
for (j = k; yytext[j]; j++)
497
for (k = j; yytext[k]; k++)
498
if (yytext[k] == 10 || yytext[k] == 13)
502
s = (char*)emalloc(k-j+1);
503
strncpy(s, yytext+j, k-j);
507
else if (!strncmp(yytext+i, "method-action:", 14))
508
{ m = (Method*)emalloc(sizeof(Method));
514
for (j = k; yytext[j]; j++)
517
for (k = j; yytext[k]; k++)
522
s = (char*)emalloc(k-j+1);
523
strncpy(s, yytext+j, k-j);
527
else if (!strncmp(yytext+i, "method-mime-type:", 17))
528
{ m = (Method*)emalloc(sizeof(Method));
530
m->mess = MIMEIN | MIMEOUT;
534
for (j = k; yytext[j]; j++)
537
for (k = j; yytext[k]; k++)
542
s = (char*)emalloc(k-j+1);
543
strncpy(s, yytext+j, k-j);
547
else if (!strncmp(yytext+i, "method-input-mime-type:", 23))
548
{ m = (Method*)emalloc(sizeof(Method));
554
for (j = k; yytext[j]; j++)
557
for (k = j; yytext[k]; k++)
562
s = (char*)emalloc(k-j+1);
563
strncpy(s, yytext+j, k-j);
567
else if (!strncmp(yytext+i, "method-output-mime-type:", 24))
568
{ m = (Method*)emalloc(sizeof(Method));
574
for (j = k; yytext[j]; j++)
577
for (k = j; yytext[k]; k++)
582
s = (char*)emalloc(k-j+1);
583
strncpy(s, yytext+j, k-j);
587
else if (!strncmp(yytext+i, "method-header-part:", 19))
588
{ m = (Method*)emalloc(sizeof(Method));
590
m->mess = HDRIN | HDROUT;
594
for (j = k; yytext[j]; j++)
597
for (k = j; yytext[k]; k++)
602
s = (char*)emalloc(k-j+1);
603
strncpy(s, yytext+j, k-j);
607
else if (!strncmp(yytext+i, "method-input-header-part:", 25))
608
{ m = (Method*)emalloc(sizeof(Method));
614
for (j = k; yytext[j]; j++)
617
for (k = j; yytext[k]; k++)
622
s = (char*)emalloc(k-j+1);
623
strncpy(s, yytext+j, k-j);
627
else if (!strncmp(yytext+i, "method-output-header-part:", 26))
628
{ m = (Method*)emalloc(sizeof(Method));
634
for (j = k; yytext[j]; j++)
637
for (k = j; yytext[k]; k++)
642
s = (char*)emalloc(k-j+1);
643
strncpy(s, yytext+j, k-j);
647
else if (!strncmp(yytext+i, "method-fault:", 13))
648
{ m = (Method*)emalloc(sizeof(Method));
654
for (j = k; yytext[j]; j++)
657
for (k = j; yytext[k]; k++)
662
s = (char*)emalloc(k-j+1);
663
strncpy(s, yytext+j, k-j);
667
else if (!strncmp(yytext+i, "type-documentation:", 19))
668
{ d = (Data*)emalloc(sizeof(Data));
673
for (j = k; yytext[j]; j++)
676
for (k = j; yytext[k]; k++)
677
if (yytext[k] == 10 || yytext[k] == 13)
681
s = (char*)emalloc(k-j+1);
682
strncpy(s, yytext+j, k-j);
687
{ sprintf(errbuf, "unrecognized gsoap directive: %s", yytext+i);
692
{ sprintf(errbuf, "unrecognized gsoap directive: %s", yytext);
700
{ sprintf(errbuf, "options directive: %s ignored in imported file(s)", yytext);
704
for (i = 10; yytext[i]; i++)
707
for (; yytext[i]; i++)
734
error_chr - lexical error in character constant. Return character 0 to
735
allow parsing to continue
739
{ lexerror("Ending-' missing in character constant");
745
error_str - lexical error in string. Return empty string to allow
750
{ lexerror("Ending-\" missing in string");
756
Character conversion functions
760
{ switch (yytext[(*p)++])
761
{ case 'a': return '\a';
762
case 'b': return '\b';
763
case 'f': return '\f';
764
case 'n': return '\n';
765
case 'r': return '\r';
766
case 't': return '\t';
767
case 'v': return '\v';
768
case 'x': return hexchar(p);
778
default: return yytext[*p-1];
785
for (i = 0; isxdigit(d = yytext[*p]) && i < 2; i++)
786
{ c = (c << 4) + (d <= '9' ? d - '0' : toupper(d) - '7');
795
for (i = 0; (d = yytext[*p]) >= '0' && d <= '7' && i < 3; i++)
796
{ c = (c << 3) + d - '0';
802
static void module(const char *name, const char *fullname)
807
char *s = emalloc(strlen(fullname)+15);
808
sprintf(s, "#include \"%sH.h\"", fullname);
809
for (pp = &pragmas; *pp; pp = &(*pp)->next)
810
if (!strcmp((*pp)->pragma, s))
813
{ *pp = (Pragma*)emalloc(sizeof(Pragma));
817
imported = (char*)emalloc(strlen(fullname)+1);
818
strcpy(imported, fullname);
819
fprintf(stderr, "Importing module '%s'\n\n", fullname);
823
typeNO = magic(name);
824
prefix = (char*)emalloc(strlen(fullname)+1);
825
strcpy(prefix, fullname);
826
fprintf(stderr, "Compiling module '%s' (magic number = %d)\n\n", fullname, typeNO);
830
static int magic(const char *name)
833
if (strlen(name) > 4)
834
semerror("#module name length must not exceed four characters");
836
for (i = 0; i < strlen(name); i++)
837
if (name[i] >= 'a' && name[i] <= 'z')
838
n = 26*n + name[i] - 'a';
839
else if (name[i] >= 'A' && name[i] <= 'Z')
840
n = 26*n + name[i] - 'A';
842
semerror("#module name must be alphabetic and the length must not exceed four characters.\nUse '#module name longname' for longer names.");
843
return 4699*n + 153424;
847
static void import(const char *file)
848
{ execerror("Cannot #import: soapcpp2 not compiled with flex");
851
static void import(const char *file)
853
struct importlist *p;
854
for (p = importlist; p; p = p->next)
855
if (!strcmp(p->name, file))
857
if (imports >= MAX_IMPORT_DEPTH)
858
execerror("Imports nested too deep");
859
instk[imports] = YY_CURRENT_BUFFER;
860
strcpy(fnstk[imports], filename);
861
lnstk[imports] = yylineno;
862
imstk[imports] = imported;
863
/* imported = NULL; this is useful to change the semantics of #import to NOT consider non-module imports to be part of the current module */
865
if (!(yyin = fopen(file, "r")))
870
{ t = strstr(s, SOAP_PATHSEP);
872
{ if (t - s >= sizeof(buf))
873
t = s + sizeof(buf) - 1;
874
strncpy(buf, s, t - s);
876
s = t + sizeof(SOAP_PATHSEP) - 1;
884
yyin = fopen(buf, "r");
889
{ sprintf(errbuf, "#import: Cannot open file \"%s\" for reading.\nHint: use option -I<path> (you can define multiple paths separated with '"SOAP_PATHSEP"')", file);
893
p = (struct importlist*)malloc(sizeof(struct importlist) + strlen(file)); /* has already + 1 byte size */
894
strcpy(p->name, file);
895
p->next = importlist;
897
strcpy(filename, file);
898
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));