7
--------------------------------------------------------------------------------
8
gSOAP XML Web services tools
9
Copyright (C) 2001-2006, Robert van Engelen, Genivia Inc. All Rights Reserved.
10
This part of the software is released under one of the following licenses:
11
GPL or Genivia's license for commercial use.
12
--------------------------------------------------------------------------------
15
This program is free software; you can redistribute it and/or modify it under
16
the terms of the GNU General Public License as published by the Free Software
17
Foundation; either version 2 of the License, or (at your option) any later
20
This program is distributed in the hope that it will be useful, but WITHOUT ANY
21
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
PARTICULAR PURPOSE. See the GNU General Public License for more details.
24
You should have received a copy of the GNU General Public License along with
25
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
26
Place, Suite 330, Boston, MA 02111-1307 USA
28
Author contact information:
29
engelen@genivia.com / engelen@acm.org
30
--------------------------------------------------------------------------------
31
A commercial use license is available from Genivia, Inc., contact@genivia.com
32
--------------------------------------------------------------------------------
34
TODO: consider adding support for non-SOAP HTTP operations
35
add headerfault output definitions
42
static void comment(const char *start, const char *middle, const char *end, const char *text);
43
static void page(const char *page, const char *title, const char *text);
44
static void section(const char *section, const char *title, const char *text);
45
static void banner(const char*);
47
static void text(const char*);
49
////////////////////////////////////////////////////////////////////////////////
51
// Definitions methods
53
////////////////////////////////////////////////////////////////////////////////
55
Definitions::Definitions()
58
void Definitions::collect(const wsdl__definitions &definitions)
59
{ // Collect information: analyze WSDL definitions and imported definitions
61
for (vector<wsdl__import>::const_iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
62
if ((*import).definitionsPtr())
63
analyze(*(*import).definitionsPtr());
66
void Definitions::analyze(const wsdl__definitions &definitions)
67
{ // Analyze WSDL and build Service information
68
int binding_count = 0;
69
// Determine number of relevant SOAP service bindings
70
for (vector<wsdl__binding>::const_iterator i = definitions.binding.begin(); i != definitions.binding.end(); ++i)
71
{ for (vector<wsdl__binding_operation>::const_iterator j = (*i).operation.begin(); j != (*i).operation.end(); ++j)
72
{ if ((*j).operationPtr() && (*j).input && (*j).input->soap__body_)
78
// Analyze and collect service data
79
for (vector<wsdl__binding>::const_iterator binding = definitions.binding.begin(); binding != definitions.binding.end(); ++binding)
80
{ // /definitions/binding/documentation
81
const char *binding_documentation = (*binding).documentation;
82
// /definitions/binding/soap:binding
83
soap__binding *soap__binding_ = (*binding).soap__binding_;
84
// /definitions/binding/soap:binding/@transport
85
const char *soap__binding_transport = NULL;
87
soap__binding_transport = soap__binding_->transport;
88
// /definitions/binding/soap:binding/@style
89
soap__styleChoice soap__binding_style = rpc;
90
if (soap__binding_ && soap__binding_->style)
91
soap__binding_style = *soap__binding_->style;
92
// /definitions/binding/http:binding
93
http__binding *http__binding_ = (*binding).http__binding_;
94
const char *http__binding_verb = NULL;
96
http__binding_verb = http__binding_->verb;
97
// /definitions/binding/operation*
98
for (vector<wsdl__binding_operation>::const_iterator operation = (*binding).operation.begin(); operation != (*binding).operation.end(); ++operation)
99
{ // /definitions/portType/operation/ associated with /definitions/binding/operation
100
wsdl__operation *wsdl__operation_ = (*operation).operationPtr();
101
// /definitions/binding/operation/soap:operation
102
soap__operation *soap__operation_ = (*operation).soap__operation_;
103
// /definitions/binding/operation/soap:operation/@style
104
soap__styleChoice soap__operation_style = soap__binding_style;
105
if (soap__operation_ && soap__operation_->style)
106
soap__operation_style = *soap__operation_->style;
107
// /definitions/binding/operation/http:operation
108
http__operation *http__operation_ = (*operation).http__operation_;
109
// /definitions/binding/operation/http:operation/@location
110
const char *http__operation_location = NULL;
111
if (http__operation_)
112
http__operation_location = http__operation_->location;
113
// /definitions/binding/operation/input
114
wsdl__ext_input *ext_input = (*operation).input;
115
// /definitions/binding/operation/output
116
wsdl__ext_output *ext_output = (*operation).output;
117
// /definitions/portType/operation
118
if (wsdl__operation_)
119
{ wsdl__input *input = wsdl__operation_->input;
120
wsdl__output *output = wsdl__operation_->output;
121
if (http__operation_)
122
{ // TODO: HTTP operation
124
else if (input && ext_input)
125
{ soap__body *input_body = ext_input->soap__body_;
126
if (ext_input->mime__multipartRelated_)
127
{ for (vector<mime__part>::const_iterator part = ext_input->mime__multipartRelated_->part.begin(); part != ext_input->mime__multipartRelated_->part.end(); ++part)
128
if ((*part).soap__body_)
129
{ input_body = (*part).soap__body_;
133
// MUST have an input, otherwise can't generate a service operation
136
if (soap__operation_style == rpc)
137
URI = input_body->namespace_;
138
else if (binding_count == 1)
139
URI = definitions.targetNamespace;
141
{ // multiple service bidings are used, each needs a unique new URI
142
URI = (char*)soap_malloc(definitions.soap, strlen(definitions.targetNamespace) + strlen((*binding).name) + 2);
143
strcpy(URI, definitions.targetNamespace);
144
if (*URI && URI[strlen(URI)-1] != '/')
146
strcat(URI, (*binding).name);
149
{ const char *prefix = types.nsprefix(service_prefix, URI);
150
const char *name = types.aname(NULL, NULL, (*binding).name); // name of service is binding name
151
Service *s = services[prefix];
153
{ s = services[prefix] = new Service();
157
s->transport = soap__binding_transport;
158
if ((*binding).portTypePtr())
159
s->type = types.aname(NULL, NULL, (*binding).portTypePtr()->name);
163
for (vector<wsdl__service>::const_iterator service = definitions.service.begin(); service != definitions.service.end(); ++service)
164
{ for (vector<wsdl__port>::const_iterator port = (*service).port.begin(); port != (*service).port.end(); ++port)
165
{ if ((*port).bindingPtr() == &(*binding))
166
{ if ((*port).soap__address_)
167
s->location.insert((*port).soap__address_->location);
168
// TODO: HTTP address for HTTP operations
169
// if ((*port).http__address_)
170
// http__address_location = http__address_->location;
171
if ((*service).documentation)
172
s->service_documentation[(*service).name] = (*service).documentation;
173
if ((*port).documentation && (*port).name)
174
s->port_documentation[(*port).name] = (*port).documentation;
175
if (binding_documentation)
176
s->binding_documentation[(*binding).name] = binding_documentation;
180
Operation *o = new Operation();
181
o->name = types.aname(NULL, NULL, wsdl__operation_->name);
184
o->style = soap__operation_style;
185
o->documentation = wsdl__operation_->documentation;
186
o->operation_documentation = (*operation).documentation;
187
o->parameterOrder = wsdl__operation_->parameterOrder;
188
if ((*operation).soap__operation_)
189
o->soapAction = (*operation).soap__operation_->soapAction;
191
{ o->soapAction = "";
192
// determine if we use SOAP 1.2 in which case soapAction is absent, this is a bit of a hack due to the lack of WSDL1.1/SOAP1.2 support and better alternatives
193
for (Namespace *p = definitions.soap->local_namespaces; p && p->id; p++)
194
{ if (p->out && !strcmp(p->id, "soap") && !strcmp(p->out, "http://schemas.xmlsoap.org/wsdl/soap12/"))
195
{ o->soapAction = NULL;
200
o->input = new Message();
201
o->input->name = (*operation).name; // RPC uses operation/@name
202
if (soap__operation_style == rpc && !input_body->namespace_)
203
{ o->input->URI = "";
204
fprintf(stderr, "Error: no soap:body namespace attribute\n");
207
o->input->URI = input_body->namespace_;
208
o->input->use = input_body->use;
209
o->input->encodingStyle = input_body->encodingStyle;
210
o->input->message = input->messagePtr();
211
o->input->part = NULL;
212
o->input->multipartRelated = ext_input->mime__multipartRelated_;
213
o->input->content = NULL;
214
if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty())
215
o->input->header = ext_input->mime__multipartRelated_->part.front().soap__header_;
217
o->input->header = ext_input->soap__header_;
218
if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty() && ext_input->mime__multipartRelated_->part.front().soap__body_)
219
o->input->body_parts = ext_input->mime__multipartRelated_->part.front().soap__body_->parts;
221
o->input->body_parts = input_body->parts;
222
if (ext_input->dime__message_)
223
o->input->layout = ext_input->dime__message_->layout;
225
o->input->layout = NULL;
226
o->input->documentation = input->documentation;
227
o->input->ext_documentation = ext_input->documentation;
228
if (soap__operation_style == document)
229
o->input_name = types.oname("__", o->URI, o->input->name);
231
o->input_name = types.oname(NULL, o->input->URI, o->input->name);
232
if (output && ext_output)
233
{ soap__body *output_body = ext_output->soap__body_;
234
if (ext_output->mime__multipartRelated_)
235
{ for (vector<mime__part>::const_iterator part = ext_output->mime__multipartRelated_->part.begin(); part != ext_output->mime__multipartRelated_->part.end(); ++part)
236
if ((*part).soap__body_)
237
{ output_body = (*part).soap__body_;
241
if (ext_output->mime__content_)
242
{ o->output = new Message();
243
o->output->name = NULL;
244
o->output->URI = NULL;
245
o->output->encodingStyle = NULL;
246
o->output->body_parts = NULL;
247
o->output->part = NULL;
248
o->output->multipartRelated = NULL;
249
o->output->content = ext_output->mime__content_;
250
o->output->message = output->messagePtr();
251
o->output->layout = NULL;
252
o->output->documentation = output->documentation;
253
o->output->ext_documentation = ext_output->documentation;
255
else if (output_body)
256
{ o->output = new Message();
257
o->output->name = (*operation).name; // RPC uses operation/@name with suffix 'Response' as set below
258
o->output->use = output_body->use;
259
// the code below is a hack around the RPC encoded response message element tag mismatch with Axis:
260
if (!output_body->namespace_ || output_body->use == encoded)
261
o->output->URI = o->input->URI; // encoded seems (?) to require the request's namespace
263
o->output->URI = output_body->namespace_;
264
o->output->encodingStyle = output_body->encodingStyle;
265
o->output->message = output->messagePtr();
266
o->output->part = NULL;
267
o->output->multipartRelated = ext_output->mime__multipartRelated_;
268
o->output->content = NULL;
269
if (ext_output->mime__multipartRelated_ && !ext_output->mime__multipartRelated_->part.empty())
270
o->output->header = ext_output->mime__multipartRelated_->part.front().soap__header_;
272
o->output->header = ext_output->soap__header_;
273
if (ext_output->mime__multipartRelated_ && !ext_output->mime__multipartRelated_->part.empty() && ext_output->mime__multipartRelated_->part.front().soap__body_)
274
o->output->body_parts = ext_output->mime__multipartRelated_->part.front().soap__body_->parts;
276
o->output->body_parts = output_body->parts;
277
if (ext_output->dime__message_)
278
o->output->layout = ext_output->dime__message_->layout;
280
o->output->layout = NULL;
281
o->output->documentation = output->documentation;
282
o->output->ext_documentation = ext_output->documentation;
283
char *s = (char*)soap_malloc(definitions.soap, strlen(o->output->name) + 9);
284
strcpy(s, o->output->name);
285
strcat(s, "Response");
286
if (soap__operation_style == document)
287
o->output_name = types.oname("__", o->URI, s);
289
o->output_name = types.oname(NULL, o->output->URI, s);
293
{ o->output_name = NULL;
296
// collect input headers and headerfaults
298
{ const vector<soap__header> *soap__header_ = NULL;
299
// check if soap header is in mime:multipartRelated
300
if (ext_input->mime__multipartRelated_)
301
{ for (vector<mime__part>::const_iterator part = ext_input->mime__multipartRelated_->part.begin(); part != ext_input->mime__multipartRelated_->part.end(); ++part)
302
if (!(*part).soap__header_.empty())
303
{ soap__header_ = &(*part).soap__header_;
308
soap__header_ = &ext_input->soap__header_;
309
for (vector<soap__header>::const_iterator header = soap__header_->begin(); header != soap__header_->end(); ++header)
310
{ Message *h = new Message();
311
h->message = (*header).messagePtr();
312
h->body_parts = NULL;
313
h->part = (*header).partPtr();
314
h->URI = (*header).namespace_;
315
if (h->part && h->part->element)
316
h->name = types.aname(NULL, NULL, h->part->element);
317
else if (h->URI && h->part && h->part->name && h->part->type)
318
h->name = types.aname(NULL, h->URI, h->part->name);
320
{ fprintf(stderr, "Error in SOAP Header part definition: input part '%s' missing?\n", h->part && h->part->name ? h->part->name : "?");
323
h->encodingStyle = (*header).encodingStyle;
324
h->use = (*header).use;
325
h->multipartRelated = NULL;
328
h->ext_documentation = NULL; // TODO: add document content
329
h->documentation = NULL; // TODO: add document content
330
s->header[h->name] = h;
331
for (vector<soap__headerfault>::const_iterator headerfault = (*header).headerfault.begin(); headerfault != (*header).headerfault.end(); ++headerfault)
332
{ // TODO: complete headerfault processing. This is rarely used.
336
// collect output headers and headerfaults
338
{ const vector<soap__header> *soap__header_ = NULL;
339
// check if soap header is in mime:multipartRelated
340
if (ext_output->mime__multipartRelated_)
341
{ for (vector<mime__part>::const_iterator part = ext_output->mime__multipartRelated_->part.begin(); part != ext_output->mime__multipartRelated_->part.end(); ++part)
342
if (!(*part).soap__header_.empty())
343
{ soap__header_ = &(*part).soap__header_;
348
soap__header_ = &ext_output->soap__header_;
349
for (vector<soap__header>::const_iterator header = soap__header_->begin(); header != soap__header_->end(); ++header)
350
{ Message *h = new Message();
351
h->message = (*header).messagePtr();
352
h->body_parts = NULL;
353
h->part = (*header).partPtr();
354
h->URI = (*header).namespace_;
355
if (h->part && h->part->element)
356
h->name = types.aname(NULL, NULL, h->part->element);
357
else if (h->URI && h->part && h->part->name && h->part->type)
358
h->name = types.aname(NULL, h->URI, h->part->name);
360
{ fprintf(stderr, "Error in SOAP Header part definition: output part '%s' missing?\n", h->part && h->part->name ? h->part->name : "?");
363
h->encodingStyle = (*header).encodingStyle;
364
h->use = (*header).use;
365
h->multipartRelated = NULL;
368
h->ext_documentation = NULL; // TODO: add document content
369
h->documentation = NULL; // TODO: add document content
370
s->header[h->name] = h;
371
for (vector<soap__headerfault>::const_iterator headerfault = (*header).headerfault.begin(); headerfault != (*header).headerfault.end(); ++headerfault)
372
{ // TODO: complete headerfault processing. This is rarely used.
377
for (vector<wsdl__ext_fault>::const_iterator ext_fault = (*operation).fault.begin(); ext_fault != (*operation).fault.end(); ++ext_fault)
378
{ if ((*ext_fault).soap__fault_ && (*ext_fault).messagePtr())
379
{ Message *f = new Message();
380
f->message = (*ext_fault).messagePtr();
381
f->body_parts = NULL;
383
f->encodingStyle = (*ext_fault).soap__fault_->encodingStyle;
384
f->URI = (*ext_fault).soap__fault_->namespace_;
385
f->use = (*ext_fault).soap__fault_->use;
386
f->multipartRelated = NULL;
389
f->ext_documentation = (*ext_fault).documentation;
390
f->name = types.aname("_", f->URI, f->message->name);
391
f->documentation = f->message->documentation;
392
o->fault.push_back(f);
393
s->fault[f->name] = f;
396
fprintf(stderr, "Error: no wsdl:definitions/binding/operation/fault/soap:fault\n");
398
s->operation.push_back(o);
401
fprintf(stderr, "Warning: no SOAP RPC operation namespace, operations will be ignored\n");
404
fprintf(stderr, "Error: no wsdl:definitions/binding/operation/input/soap:body\n");
407
fprintf(stderr, "Error: no wsdl:definitions/portType/operation/input\n");
410
fprintf(stderr, "Error: no wsdl:definitions/portType/operation\n");
415
void Definitions::compile(const wsdl__definitions& definitions)
416
{ // compile the definitions and generate gSOAP header file
418
if (definitions.name)
419
defs = types.aname(NULL, NULL, definitions.name);
423
fprintf(stream, "/* NOTE:\n\n - Compile this file with soapcpp2 to complete the code generation process.\n - Use soapcpp2 option -I to specify paths for #import\n To build with STL, 'stlvector.h' is imported from 'import' dir in package.\n - Use wsdl2h options -c and -s to generate pure C code or C++ code without STL.\n - Use 'typemap.dat' to control schema namespace bindings and type mappings.\n It is strongly recommended to customize the names of the namespace prefixes\n generated by wsdl2h. To do so, modify the prefix bindings in the Namespaces\n section below and add the modified lines to 'typemap.dat' to rerun wsdl2h.\n - Use Doxygen (www.doxygen.org) to browse this file.\n - Use wsdl2h option -l to view the software license terms.\n\n DO NOT include this file directly into your project.\n Include only the soapcpp2-generated headers and source code files.\n*/\n");
424
// gsoap compiler options: 'w' disables WSDL/schema output to avoid file collisions
426
fprintf(stream, "\n//gsoapopt cw\n");
428
fprintf(stream, "\n//gsoapopt w\n");
429
banner(definitions.targetNamespace?definitions.targetNamespace:"targetNamespace");
430
// copy documentation from WSDL definitions
431
if (definitions.documentation)
432
{ fprintf(stream, "/* WSDL Documentation:\n\n");
433
text(definitions.documentation);
434
fprintf(stream, "*/\n\n");
438
fprintf(stream, "/*\n%s*/\n\n", licensenotice);
440
if (definitions.version)
442
fprintf(stream, "#define SOAP_WSDL_VERSION \"%s\"\n", definitions.version);
446
{ fprintf(stream, "\n// dom.h declares the DOM xsd__anyType object (compiler and link with dom.cpp)\n");
448
fprintf(stream, "#import \"%s/dom.h\"\n", import_path);
450
fprintf(stream, "#import \"dom.h\"\n");
452
if (!cflag && !sflag)
453
{ fprintf(stream, "\n// STL vector containers (use option -s to disable)\n");
455
fprintf(stream, "#import \"%s/stlvector.h\"\n", import_path);
457
fprintf(stream, "#import \"stlvector.h\"\n");
461
fprintf(stream, "#import \"%s/", import_path);
463
fprintf(stream, "#import \"");
464
fprintf(stream, "xsd.h\"\t// import primitive XSD types.\n");
466
for (SetOfString::const_iterator u = exturis.begin(); u != exturis.end(); ++u)
467
{ bool found = false;
468
size_t n = strlen(*u);
469
for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
470
{ if (**i == '"' && !strncmp(*u, *i + 1, n))
476
{ for (SetOfString::const_iterator j = definitions.builtinElements().begin(); j != definitions.builtinElements().end(); ++j)
477
{ if (**j == '"' && !strncmp(*u, *j + 1, n))
484
{ for (SetOfString::const_iterator k = definitions.builtinAttributes().begin(); k != definitions.builtinAttributes().end(); ++k)
485
{ if (**k == '"' && !strncmp(*u, *k + 1, n))
493
fprintf(stderr, "import %s\n", *u);
495
fprintf(stream, "#import \"%s/%s.h\"\t// %s = <%s>\n", import_path, types.nsprefix(NULL, *u), types.nsprefix(NULL, *u), *u);
497
fprintf(stream, "#import \"%s.h\"\t// %s = <%s>\n", types.nsprefix(NULL, *u), types.nsprefix(NULL, *u), *u);
500
banner("Schema Namespaces");
501
// determine if we must use SOAP 1.2, this is a bit of a hack due to the lack of WSDL1.1/SOAP1.2 support and better alternatives
502
for (Namespace *p = definitions.soap->local_namespaces; p && p->id; p++)
503
{ // p->out is set to the actual namespace name that matches the p->in pattern
504
if (p->out && !strcmp(p->id, "soap") && !strcmp(p->out, "http://schemas.xmlsoap.org/wsdl/soap12/"))
505
{ fprintf(stream, "// This service uses SOAP 1.2 namespaces:\n");
506
fprintf(stream, schemaformat, "SOAP-ENV", "namespace", "http://www.w3.org/2003/05/soap-envelope");
507
fprintf(stream, schemaformat, "SOAP-ENC", "namespace", "http://www.w3.org/2003/05/soap-encoding");
511
if (definitions.types)
512
{ fprintf(stream, "\n/* NOTE:\n\nIt is strongly recommended to customize the names of the namespace prefixes\ngenerated by wsdl2h. To do so, modify the prefix bindings below and add the\nmodified lines to typemap.dat to rerun wsdl2h:\n\n");
513
if (definitions.targetNamespace && *definitions.targetNamespace)
514
fprintf(stream, "%s = \"%s\"\n", types.nsprefix(service_prefix, definitions.targetNamespace), definitions.targetNamespace);
515
for (vector<xs__schema*>::const_iterator schema1 = definitions.types->xs__schema_.begin(); schema1 != definitions.types->xs__schema_.end(); ++schema1)
516
if (!definitions.targetNamespace || strcmp((*schema1)->targetNamespace, definitions.targetNamespace))
517
fprintf(stream, "%s = \"%s\"\n", types.nsprefix(NULL, (*schema1)->targetNamespace), (*schema1)->targetNamespace);
518
fprintf(stream, "\n*/\n\n");
519
for (vector<xs__schema*>::const_iterator schema2 = definitions.types->xs__schema_.begin(); schema2 != definitions.types->xs__schema_.end(); ++schema2)
520
fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema2)->targetNamespace), "namespace", (*schema2)->targetNamespace);
521
for (vector<xs__schema*>::const_iterator schema3 = definitions.types->xs__schema_.begin(); schema3 != definitions.types->xs__schema_.end(); ++schema3)
522
{ if ((*schema3)->elementFormDefault == (*schema3)->attributeFormDefault)
523
fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "form", (*schema3)->elementFormDefault == qualified ? "qualified" : "unqualified");
525
{ fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "elementForm", (*schema3)->elementFormDefault == qualified ? "qualified" : "unqualified");
526
fprintf(stream, schemaformat, types.nsprefix(NULL, (*schema3)->targetNamespace), "attributeForm", (*schema3)->attributeFormDefault == qualified ? "qualified" : "unqualified");
530
banner("Schema Types");
531
// generate the prototypes first: these should allow use before def, e.g. class names then generate the defs
532
// check if xsd:anyType is used
533
if (!cflag && !pflag)
534
{ for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
535
{ if (!cflag && !strcmp(*i, "xs:anyType"))
542
{ fprintf(stderr, "\nWarning -d option: -p option disabled and xsd__anyType base class removed.\nUse run-time SOAP_DOM_NODE flag to deserialize class instances into DOM nodes.\n");
543
fprintf(stream, "\n/*\nWarning -d option used: -p option disabled and xsd:anyType base class removed.\nUse run-time SOAP_DOM_NODE flag to deserialize class instances into DOM nodes.\nA DOM node is represented by the xsd__anyType object implemented in dom.cpp.\n*/\n\n");
546
// define xsd:anyType first, if used
549
t = types.cname(NULL, NULL, "xs:anyType");
550
s = types.deftypemap[t];
554
fprintf(stream, "%s\n", s);
556
s = types.usetypemap[t];
559
fprintf(stream, "// xsd.h: should define type %s\n", s);
560
types.knames.insert(s);
564
{ fprintf(stderr, "Error: no xsd__anyType defined in type map\n");
568
// produce built-in primitive types, limited to the ones that are used only
570
fprintf(stderr, "\nGenerating built-in types\n");
571
for (SetOfString::const_iterator i = definitions.builtinTypes().begin(); i != definitions.builtinTypes().end(); ++i)
573
if (!cflag && !strcmp(*i, "xs:anyType"))
575
t = types.cname(NULL, NULL, *i);
576
s = types.deftypemap[t];
580
fprintf(stream, "\n/// Imported type %s from typemap %s.\n", *i, mapfile?mapfile:"");
582
fprintf(stream, "\n/// Built-in type \"%s\".\n", *i);
584
fprintf(stream, "// (declaration of %s removed by option -m)\n", t);
588
s = types.usetypemap[t];
590
{ if (mflag && **i != '"')
591
fprintf(stream, "\n// xsd.h: typemap override of type %s with %s\n", t, s);
592
if (types.knames.find(s) == types.knames.end())
593
types.knames.insert(s);
599
fprintf(stream, "\n// Imported type %s defined by %s\n", *i, t);
601
{ s = types.tname(NULL, NULL, "xsd:string");
602
fprintf(stream, "\n/// Primitive built-in type \"%s\"\n", *i);
603
fprintf(stream, "typedef %s %s;\n", s, t);
604
types.deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, NULL, NULL, *i);
608
fprintf(stream, "\n// Imported type %s defined by %s\n", *i, t);
610
fprintf(stream, "\n// xsd.h: should define type %s\n", t);
611
types.deftname(TYPEDEF, NULL, false, NULL, NULL, *i);
613
if (pflag && !strncmp(*i, "xs:", 3)) // only xsi types are polymorph
614
{ s = types.aname(NULL, NULL, *i);
616
{ fprintf(stream, "\n/// Class wrapper for built-in type \"%s\" derived from xsd__anyType\n", *i);
617
fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
618
fprintf(stream, elementformat, types.tname(NULL, NULL, *i), "__item;");
619
fprintf(stream, "\n};\n");
621
types.knames.insert(s);
624
// produce built-in primitive elements, limited to the ones that are used only
626
fprintf(stderr, "\nGenerating built-in elements\n");
627
for (SetOfString::const_iterator j = definitions.builtinElements().begin(); j != definitions.builtinElements().end(); ++j)
629
t = types.cname("_", NULL, *j);
630
s = types.deftypemap[t];
634
fprintf(stream, "\n/// Imported element %s from typemap %s.\n", *j, mapfile?mapfile:"");
636
fprintf(stream, "\n/// Built-in element \"%s\".\n", *j);
638
fprintf(stream, "// (declaration of %s removed by option -m)\n", t);
642
s = types.usetypemap[t];
644
{ if (mflag && **j != '"')
645
fprintf(stream, "\n// xsd.h: typemap override of element %s with %s\n", t, s);
646
if (types.knames.find(s) == types.knames.end())
647
types.knames.insert(s);
653
fprintf(stream, "\n// Imported element %s declared as %s\n", *j, t);
655
{ fprintf(stream, "\n/// Built-in element \"%s\".\n", *j);
656
fprintf(stream, "typedef _XML %s;\n", t);
657
types.deftname(TYPEDEF, NULL, true, "_", NULL, *j); // already pointer
661
fprintf(stream, "\n// Imported element %s declared as %s\n", *j, t);
663
fprintf(stream, "\n// xsd.h: should define element %s\n", t);
664
types.deftname(TYPEDEF, NULL, false, "_", NULL, *j);
667
// produce built-in primitive attributes, limited to the ones that are used only
669
fprintf(stderr, "\nGenerating built-in attributes\n");
670
for (SetOfString::const_iterator k = definitions.builtinAttributes().begin(); k != definitions.builtinAttributes().end(); ++k)
672
t = types.cname("_", NULL, *k);
673
s = types.deftypemap[t];
677
fprintf(stream, "\n/// Imported attribute %s from typemap %s.\n", *k, mapfile?mapfile:"");
679
fprintf(stream, "\n/// Built-in attribute \"%s\".\n", *k);
681
fprintf(stream, "// (declaration of %s removed by option -m)\n", t);
685
s = types.usetypemap[t];
687
{ if (mflag && **k != '"')
688
fprintf(stream, "\n// xsd.h: typemap override of attribute %s with %s\n", t, s);
689
if (types.knames.find(s) == types.knames.end())
690
types.knames.insert(s);
694
{ s = types.tname(NULL, NULL, "xsd:string");
697
fprintf(stream, "\n// Imported attribute %s declared as %s\n", *k, t);
699
{ fprintf(stream, "\n/// Built-in attribute \"%s\".\n", *k);
700
fprintf(stream, "typedef %s %s;\n", s, t);
704
fprintf(stream, "// Imported attribute %s declared as %s\n", *k, t);
706
fprintf(stream, "// xsd.h: should define attribute %s\n", t);
707
types.deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, "_", NULL, *k);
711
// define class/struct types first
712
if (definitions.types)
713
{ comment("Definitions", defs, "types", definitions.types->documentation);
714
fprintf(stream, "\n");
715
for (vector<xs__schema*>::const_iterator schema4 = definitions.types->xs__schema_.begin(); schema4 != definitions.types->xs__schema_.end(); ++schema4)
717
fprintf(stderr, "\nDefining types in %s\n", (*schema4)->targetNamespace);
718
for (vector<xs__complexType>::const_iterator complexType = (*schema4)->complexType.begin(); complexType != (*schema4)->complexType.end(); ++complexType)
719
types.define((*schema4)->targetNamespace, NULL, *complexType);
721
fprintf(stderr, "\nDefining elements in %s\n", (*schema4)->targetNamespace);
722
for (vector<xs__element>::const_iterator element = (*schema4)->element.begin(); element != (*schema4)->element.end(); ++element)
723
{ if (!(*element).type && !(*element).abstract)
724
{ if ((*element).complexTypePtr())
725
types.define((*schema4)->targetNamespace, (*element).name, *(*element).complexTypePtr());
726
else if (!(*element).simpleTypePtr())
727
{ fprintf(stream, "\n/// Element \"%s\":%s.\n", (*schema4)->targetNamespace, (*element).name);
729
{ const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema4)->targetNamespace, (*element).name);
731
fprintf(stream, "typedef _XML %s;\n", t);
733
fprintf(stream, "// Element definition intentionally left blank.\n");
736
{ const char *s = types.cname("_", (*schema4)->targetNamespace, (*element).name);
737
types.ptrtypemap[s] = types.usetypemap[s] = "_XML";
738
fprintf(stream, "/// Note: use wsdl2h option -g to generate this global element declaration.\n");
744
// visit types with lowest base level first
748
{ found = (baseLevel == 1);
749
for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
750
{ for (vector<xs__simpleType>::iterator simpleType = (*schema)->simpleType.begin(); simpleType != (*schema)->simpleType.end(); ++simpleType)
751
{ if ((*simpleType).baseLevel() == baseLevel)
753
types.gen((*schema)->targetNamespace, NULL, *simpleType, false);
756
for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
757
{ if (!(*element).type && (*element).simpleTypePtr() && (*element).simpleTypePtr()->baseLevel() == baseLevel)
760
fprintf(stream, "/// Element \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*element).name, (*element).type);
761
types.document((*element).annotation);
762
types.gen((*schema)->targetNamespace, (*element).name, *(*element).simpleTypePtr(), false);
764
if (!(*element).type && (*element).complexTypePtr() && (*element).complexTypePtr()->baseLevel() == baseLevel)
767
for (vector<xs__attribute>::const_iterator attribute = (*schema)->attribute.begin(); attribute != (*schema)->attribute.end(); ++attribute)
768
{ if (!(*attribute).type && (*attribute).simpleTypePtr() && (*attribute).simpleTypePtr()->baseLevel() == baseLevel)
770
if ((*attribute).type)
771
fprintf(stream, "/// Attribute \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*attribute).name, (*attribute).type);
772
types.document((*attribute).annotation);
773
types.gen((*schema)->targetNamespace, (*attribute).name, *(*attribute).simpleTypePtr(), false); // URI = NULL won't generate type in schema (type without namespace qualifier)
776
for (vector<xs__complexType>::iterator complexType = (*schema)->complexType.begin(); complexType != (*schema)->complexType.end(); ++complexType)
777
{ if ((*complexType).baseLevel() == baseLevel)
783
// generate complex type defs. Problem: what if a simpleType restriction/extension depends on a complexType simpleContent restriction/extension?
784
int maxLevel = baseLevel;
785
for (baseLevel = 1; baseLevel < maxLevel; ++baseLevel)
786
{ for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
787
{ for (vector<xs__complexType>::iterator complexType = (*schema)->complexType.begin(); complexType != (*schema)->complexType.end(); ++complexType)
788
{ if ((*complexType).baseLevel() == baseLevel)
789
types.gen((*schema)->targetNamespace, NULL, *complexType, false);
791
for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
792
{ if (!(*element).type && (*element).complexTypePtr() && (*element).complexTypePtr()->baseLevel() == baseLevel)
793
{ fprintf(stream, "\n\n/// Element \"%s\":%s of complexType.\n", (*schema)->targetNamespace, (*element).name);
794
types.document((*element).annotation);
795
types.gen((*schema)->targetNamespace, (*element).name, *(*element).complexTypePtr(), false);
800
// option to consider: generate local complexTypes iteratively
802
for (MapOfStringToType::const_iterator local = types.locals.begin(); local != types.locals.end(); ++local)
803
{ types.gen(NULL, (*local).first, *(*local).second);
806
for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
808
fprintf(stderr, "\nGenerating elements in %s\n", (*schema)->targetNamespace);
809
for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
810
{ if ((*element).name && (*element).type && !(*element).abstract)
811
{ fprintf(stream, "\n/// Element \"%s\":%s of type %s.\n", (*schema)->targetNamespace, (*element).name, (*element).type);
812
types.document((*element).annotation);
813
if (!types.is_defined("_", (*schema)->targetNamespace, (*element).name))
814
{ const char *s = types.tname(NULL, (*schema)->targetNamespace, (*element).type);
815
const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema)->targetNamespace, (*element).name);
817
{ if (strncmp(s, "char", 4) && strchr(s, '*')) // don't want pointer typedef, unless char*
818
{ size_t n = strlen(s);
819
char *r = (char*)malloc(n);
820
strncpy(r, s, n - 1);
822
fprintf(stream, "typedef %s %s;\n", r, t);
826
fprintf(stream, "typedef %s %s;\n", s, t);
829
fprintf(stream, "/// Note: use wsdl2h option -g to generate this global element declaration.\n");
832
{ const char *s = types.cname("_", (*schema)->targetNamespace, (*element).name);
833
const char *t = types.deftypemap[s];
835
{ fprintf(stream, "/// Imported element %s from typemap %s.\n", s, mapfile?mapfile:"");
839
fprintf(stream, "// '%s' element definition intentionally left blank.\n", types.cname("_", (*schema)->targetNamespace, (*element).name));
844
fprintf(stderr, "\nGenerating attributes in %s\n", (*schema)->targetNamespace);
845
for (vector<xs__attribute>::iterator attribute = (*schema)->attribute.begin(); attribute != (*schema)->attribute.end(); ++attribute)
846
{ if ((*attribute).name && (*attribute).type)
847
{ fprintf(stream, "\n/// Attribute \"%s\":%s of simpleType %s.\n", (*schema)->targetNamespace, (*attribute).name, (*attribute).type);
848
types.document((*attribute).annotation);
849
if (!types.is_defined("_", (*schema)->targetNamespace, (*attribute).name))
850
{ const char *s = types.tname(NULL, (*schema)->targetNamespace, (*attribute).type);
851
const char *t = types.deftname(TYPEDEF, NULL, false, "_", (*schema)->targetNamespace, (*attribute).name);
853
{ if (strncmp(s, "char", 4) && strchr(s, '*')) // don't want pointer typedef, unless char*
854
{ size_t n = strlen(s);
855
char *r = (char*)malloc(n);
856
strncpy(r, s, n - 1);
858
fprintf(stream, "typedef %s %s;\n", r, t);
862
fprintf(stream, "typedef %s %s;\n", s, t);
865
fprintf(stream, "/// Note: use wsdl2h option -g to generate this global attribute declaration.\n");
868
{ const char *s = types.cname("_", (*schema)->targetNamespace, (*attribute).name);
869
const char *t = types.deftypemap[s];
871
{ fprintf(stream, "/// Imported attribute %s from typemap %s.\n", s, mapfile?mapfile:"");
875
fprintf(stream, "// '%s' attribute definition intentionally left blank.\n", types.cname("_", (*schema)->targetNamespace, (*attribute).name));
882
fprintf(stderr, "\nCollecting service bindings");
883
collect(definitions);
884
if (!services.empty())
885
{ banner("Services");
886
for (MapOfStringToService::const_iterator service1 = services.begin(); service1 != services.end(); ++service1)
887
{ Service *sv = (*service1).second;
888
if (sv && sv->prefix)
889
{ fprintf(stream, "\n");
891
fprintf(stream, serviceformat, sv->prefix, "name", sv->name, "");
893
fprintf(stream, serviceformat, sv->prefix, "type", sv->type, "");
894
for (SetOfString::const_iterator port = sv->location.begin(); port != sv->location.end(); ++port)
895
fprintf(stream, serviceformat, sv->prefix, "port", (*port), "");
897
fprintf(stream, serviceformat, sv->prefix, "namespace", sv->URI, "");
899
fprintf(stream, serviceformat, sv->prefix, "transport", sv->transport, "");
902
fprintf(stream, "\n/** @mainpage %s Definitions\n", definitions.name?definitions.name:"Service");
903
if (definitions.version)
904
{ section(defs, "_version Version", NULL);
905
text(definitions.version);
907
if (definitions.documentation)
908
{ section(defs, "_documentation Documentation", NULL);
909
text(definitions.documentation);
911
if (definitions.types && definitions.types->documentation)
912
{ section(defs, "_types Types", NULL);
913
text(definitions.types->documentation);
915
section(defs, "_bindings Bindings", NULL);
916
for (MapOfStringToService::const_iterator service2 = services.begin(); service2 != services.end(); ++service2)
917
{ Service *sv = (*service2).second;
919
fprintf(stream, " - @ref %s\n", sv->name);
921
fprintf(stream, "\n*/\n");
922
for (MapOfStringToService::const_iterator service3 = services.begin(); service3 != services.end(); ++service3)
923
{ Service *sv = (*service3).second;
925
{ fprintf(stream, "\n/**\n");
926
page(sv->name, " Binding", sv->name);
927
for (MapOfStringToString::const_iterator service_doc = sv->service_documentation.begin(); service_doc != sv->service_documentation.end(); ++service_doc)
928
{ const char *name = types.aname(NULL, NULL, (*service_doc).first);
929
section(name, "_service Service Documentation", (*service_doc).first);
930
text((*service_doc).second);
932
for (MapOfStringToString::const_iterator port_doc = sv->port_documentation.begin(); port_doc != sv->port_documentation.end(); ++port_doc)
933
{ const char *name = types.aname(NULL, NULL, (*port_doc).first);
934
section(name, "_port Port Documentation", (*port_doc).first);
935
text((*port_doc).second);
937
for (MapOfStringToString::const_iterator binding_doc = sv->binding_documentation.begin(); binding_doc != sv->binding_documentation.end(); ++binding_doc)
938
{ const char *name = types.aname(NULL, NULL, (*binding_doc).first);
939
section(name, "_binding Binding Documentation", (*binding_doc).first);
940
text((*binding_doc).second);
942
section(sv->name, "_operations Operations of Binding ", sv->name);
943
for (vector<Operation*>::const_iterator op = sv->operation.begin(); op != sv->operation.end(); ++op)
944
{ if (*op && (*op)->input_name)
945
fprintf(stream, " - @ref %s\n", (*op)->input_name);
947
section((*sv).name, "_ports Endpoints of Binding ", sv->name);
948
for (SetOfString::const_iterator port = sv->location.begin(); port != sv->location.end(); ++port)
949
fprintf(stream, " - %s\n", *port);
950
fprintf(stream, "\nNote: use wsdl2h option -N to change the service binding prefix name\n\n*/\n");
956
fprintf(stream, "\n} // namespace %s\n", cppnamespace);
957
fprintf(stream, "\n/* End of %s */\n", outfile?outfile:"file");
960
void Definitions::generate()
961
{ MapOfStringToMessage headers;
962
MapOfStringToMessage faults;
964
for (MapOfStringToService::const_iterator service1 = services.begin(); service1 != services.end(); ++service1)
965
{ if ((*service1).second)
966
{ for (MapOfStringToMessage::const_iterator header = (*service1).second->header.begin(); header != (*service1).second->header.end(); ++header)
967
headers[(*header).first] = (*header).second;
968
for (MapOfStringToMessage::const_iterator fault = (*service1).second->fault.begin(); fault != (*service1).second->fault.end(); ++fault)
969
faults[(*fault).first] = (*fault).second;
972
// Generate SOAP Header definition
973
t = types.deftypemap["SOAP_ENV__Header"];
975
{ banner("Custom SOAP Header");
978
else if (!jflag && !headers.empty())
979
{ banner("SOAP Header");
980
fprintf(stream, "/**\n\nThe SOAP Header is part of the gSOAP context and its content is accessed\nthrough the soap.header variable. You may have to set the soap.actor variable\nto serialize SOAP Headers with SOAP-ENV:actor or SOAP-ENV:role attributes.\nUse option -j to omit.\n\n*/\n");
981
fprintf(stream, "struct SOAP_ENV__Header\n{\n");
982
for (MapOfStringToMessage::const_iterator header = headers.begin(); header != headers.end(); ++header)
983
{ if ((*header).second->URI && !types.uris[(*header).second->URI])
984
fprintf(stream, schemaformat, types.nsprefix(NULL, (*header).second->URI), "namespace", (*header).second->URI);
985
comment("Header", (*header).first, "WSDL", (*header).second->ext_documentation);
986
comment("Header", (*header).first, "SOAP", (*header).second->documentation);
987
fprintf(stream, elementformat, "mustUnderstand", "// must be understood by receiver");
988
fprintf(stream, "\n");
989
if ((*header).second->part && (*header).second->part->elementPtr())
990
{ fprintf(stream, "/// \"%s\" SOAP Header part element\n", (*header).second->part->name);
991
types.gen(NULL, *(*header).second->part->elementPtr());
993
else if ((*header).second->part && (*header).second->part->type)
994
{ fprintf(stream, elementformat, types.pname(true, NULL, NULL, (*header).second->part->type), types.aname(NULL, (*header).second->URI, (*header).second->part->name));
995
fprintf(stream, ";\n");
998
{ if ((*header).second->part && (*header).second->part->element)
999
fprintf(stream, elementformat, types.pname(true, "_", NULL, (*header).second->part->element), (*header).first);
1001
fprintf(stream, pointerformat, (*header).first, (*header).first);
1002
fprintf(stream, ";\t///< TODO: Please check element name and type (imported type)\n");
1005
types.modify("SOAP_ENV__Header");
1006
fprintf(stream, "\n};\n");
1008
// Generate Fault detail element definitions
1009
for (MapOfStringToMessage::const_iterator fault = faults.begin(); fault != faults.end(); ++fault)
1010
{ if ((*fault).second->use == encoded)
1011
{ banner("SOAP Fault Detail Message");
1012
fprintf(stream, "/// SOAP Fault detail message \"%s:%s\"\n", (*fault).second->URI, (*fault).second->message->name);
1013
comment("Fault", (*fault).first, "WSDL", (*fault).second->ext_documentation);
1014
comment("Fault", (*fault).first, "SOAP", (*fault).second->documentation);
1016
fprintf(stream, "struct %s\n{", (*fault).first);
1018
fprintf(stream, "class %s\n{ public:", (*fault).first);
1019
(*fault).second->generate(types, ";", false, true, false);
1021
{ fprintf(stream, "\n");
1022
fprintf(stream, pointerformat, "struct soap", "soap");
1023
fprintf(stream, ";");
1025
fprintf(stream, "\n};\n");
1027
fprintf(stream, "typedef struct %s %s;\n", (*fault).first, (*fault).first);
1028
if ((*fault).second->URI && !types.uris[(*fault).second->URI])
1029
fprintf(stream, schemaformat, types.nsprefix(NULL, (*fault).second->URI), "namespace", (*fault).second->URI);
1032
t = types.deftypemap["SOAP_ENV__Detail"];
1034
{ banner("Custom SOAP Detail");
1037
else if (!jflag && !faults.empty())
1038
{ SetOfString fault_elements;
1039
banner("SOAP Fault Detail");
1040
fprintf(stream, "/**\n\nThe SOAP Fault is part of the gSOAP context and its content is accessed\nthrough the soap.fault->detail variable (SOAP 1.1) or the\nsoap.fault->SOAP_ENV__Detail variable (SOAP 1.2).\nUse option -j to omit.\n\n*/\n");
1041
fprintf(stream, "struct SOAP_ENV__Detail\n{\n");
1042
for (MapOfStringToMessage::const_iterator fault = faults.begin(); fault != faults.end(); ++fault)
1043
{ if ((*fault).second->URI && !types.uris[(*fault).second->URI])
1044
fprintf(stream, schemaformat, types.nsprefix(NULL, (*fault).second->URI), "namespace", (*fault).second->URI);
1045
comment("Fault", (*fault).first, "WSDL", (*fault).second->ext_documentation);
1046
comment("Fault", (*fault).first, "SOAP", (*fault).second->documentation);
1047
if ((*fault).second->use == literal)
1048
{ for (vector<wsdl__part>::const_iterator part = (*fault).second->message->part.begin(); part != (*fault).second->message->part.end(); ++part)
1049
{ if ((*part).elementPtr())
1050
{ if (fault_elements.find((*part).element) == fault_elements.end())
1051
{ if ((*part).elementPtr()->type)
1052
fprintf(stream, elementformat, types.pname(true, NULL, NULL, (*part).elementPtr()->type), types.aname(NULL, (*fault).second->URI, (*part).element));
1054
fprintf(stream, elementformat, types.pname(true, "_", NULL, (*part).element), types.aname(NULL, (*fault).second->URI, (*part).element));
1055
fprintf(stream, ";\n");
1056
fault_elements.insert((*part).element);
1058
fprintf(stream, "///< SOAP Fault element \"%s\" part \"%s\"\n", (*part).element?(*part).element:"", (*part).name?(*part).name:"");
1060
else if ((*part).name && (*part).type)
1061
{ if (fault_elements.find((*part).name) == fault_elements.end())
1062
{ fprintf(stream, elementformat, types.pname(true, NULL, NULL, (*part).type), types.aname("_", (*fault).second->URI, (*part).name));
1063
fprintf(stream, ";\n");
1064
fault_elements.insert((*part).name);
1066
fprintf(stream, "///< SOAP Fault type \"%s\" part \"%s\"\n", (*part).type, (*part).name);
1069
fprintf(stream, "// Unknown SOAP Fault element \"%s\" part \"%s\"\n", (*fault).second->message->name, (*part).name?(*part).name:"");
1073
{ fprintf(stream, pointerformat, (*fault).first, types.aname(NULL, (*fault).second->URI, (*fault).second->message->name));
1074
fprintf(stream, ";\t///< SOAP Fault detail message \"%s\":%s\n", (*fault).second->URI, (*fault).second->message->name);
1077
types.modify("SOAP_ENV__Detail");
1078
fprintf(stream, elementformat, "int", "__type");
1079
fprintf(stream, ";\t///< set to SOAP_TYPE_X for a serializable type X\n");
1080
fprintf(stream, pointerformat, "void", "fault");
1081
fprintf(stream, ";\t///< points to serializable object X or NULL\n");
1083
{ fprintf(stream, pointerformat, "xsd__anyType", "__any");
1084
fprintf(stream, ";\t///< Catch any element content in DOM.\n");
1087
{ fprintf(stream, elementformat, "_XML", "__any");
1088
fprintf(stream, ";\t///< Catch any element content in XML string.\n");
1090
fprintf(stream, "};\n");
1092
/* The SOAP Fault struct below is autogenerated by soapcpp2 (kept here for future mods)
1093
if (!mflag && !faults.empty())
1094
{ fprintf(stream, "struct SOAP_ENV__Code\n{\n");
1095
fprintf(stream, elementformat, "_QName", "SOAP_ENV__Value");
1096
fprintf(stream, ";\n");
1097
fprintf(stream, pointerformat, "char", "SOAP_ENV__Node");
1098
fprintf(stream, ";\n");
1099
fprintf(stream, pointerformat, "char", "SOAP_ENV__Role");
1100
fprintf(stream, ";\n};\n");
1101
fprintf(stream, "struct SOAP_ENV__Detail\n{\n");
1102
fprintf(stream, elementformat, "int", "__type");
1103
fprintf(stream, ";\n");
1104
fprintf(stream, pointerformat, "void", "fault");
1105
fprintf(stream, ";\n");
1106
fprintf(stream, elementformat, "_XML", "__any");
1107
fprintf(stream, ";\n};\n");
1108
fprintf(stream, "struct SOAP_ENV__Fault\n{\n");
1109
fprintf(stream, elementformat, "_QName", "faultcode");
1110
fprintf(stream, ";\n");
1111
fprintf(stream, pointerformat, "char", "faultstring");
1112
fprintf(stream, ";\n");
1113
fprintf(stream, pointerformat, "char", "faultactor");
1114
fprintf(stream, ";\n");
1115
fprintf(stream, pointerformat, "struct SOAP_ENV__Detail", "detail");
1116
fprintf(stream, ";\n");
1117
fprintf(stream, pointerformat, "struct SOAP_ENV__Code", "SOAP_ENV__Code");
1118
fprintf(stream, ";\n");
1119
fprintf(stream, pointerformat, "char", "SOAP_ENV__Reason");
1120
fprintf(stream, ";\n");
1121
fprintf(stream, pointerformat, "struct SOAP_ENV__Detail", "SOAP_ENV__Detail");
1122
fprintf(stream, ";\n};\n");
1125
for (MapOfStringToService::const_iterator service2 = services.begin(); service2 != services.end(); ++service2)
1126
if ((*service2).second)
1127
(*service2).second->generate(types);
1130
////////////////////////////////////////////////////////////////////////////////
1134
////////////////////////////////////////////////////////////////////////////////
1144
void Service::generate(Types& types)
1147
for (vector<Operation*>::const_iterator op2 = operation.begin(); op2 != operation.end(); ++op2)
1148
{ if (*op2 && (*op2)->input)
1149
{ bool flag = false, anonymous = ((*op2)->style != document && (*op2)->parameterOrder != NULL);
1150
banner((*op2)->input_name);
1151
if ((*op2)->output && (*op2)->output_name)
1152
{ if ((*op2)->style == document)
1153
flag = (*op2)->output->message && (*op2)->output->message->part.size() == 1;
1155
flag = (*op2)->output->message && (*op2)->output->use == encoded && (*op2)->output->message->part.size() == 1 && !(*(*op2)->output->message->part.begin()).simpleTypePtr() && !(*(*op2)->output->message->part.begin()).complexTypePtr();
1156
if (flag && (*op2)->input->message && (*(*op2)->output->message->part.begin()).element)
1157
for (vector<wsdl__part>::const_iterator part = (*op2)->input->message->part.begin(); part != (*op2)->input->message->part.end(); ++part)
1158
if ((*part).element && !strcmp((*part).element, (*(*op2)->output->message->part.begin()).element))
1161
{ fprintf(stream, "/// Operation response struct \"%s\" of service binding \"%s\" operation \"%s\"\n", (*op2)->output_name, name, (*op2)->input_name);
1162
fprintf(stream, "struct %s\n{", (*op2)->output_name);
1163
(*op2)->output->generate(types, ";", anonymous, true, false);
1164
fprintf(stream, "\n};\n");
1167
fprintf(stream, "\n/// Operation \"%s\" of service binding \"%s\"\n\n/**\n\nOperation details:\n\n", (*op2)->input_name, name);
1168
if ((*op2)->documentation)
1169
text((*op2)->documentation);
1170
if ((*op2)->operation_documentation)
1171
text((*op2)->operation_documentation);
1172
if ((*op2)->input->documentation)
1173
{ fprintf(stream, "Input request:\n");
1174
text((*op2)->input->documentation);
1176
if ((*op2)->input->ext_documentation)
1177
{ fprintf(stream, "Input request:\n");
1178
text((*op2)->input->ext_documentation);
1181
{ if ((*op2)->output->documentation)
1182
{ fprintf(stream, "Output response:\n");
1183
text((*op2)->output->documentation);
1185
if ((*op2)->output->ext_documentation)
1186
{ fprintf(stream, "Output response:\n");
1187
text((*op2)->output->ext_documentation);
1191
{ if ((*op2)->output->content)
1192
{ fprintf(stream, " - Response has MIME content");
1193
if ((*op2)->output->content->type)
1194
{ fprintf(stream, " type=\"");
1195
text((*op2)->output->content->type);
1196
fprintf(stream, "\"");
1198
fprintf(stream, "\n TODO: this form of MIME content response is not automatically handled.\n Use one-way request and implement code to parse response.\n");
1202
fprintf(stream, " - One-way message\n");
1203
if ((*op2)->style == document)
1204
fprintf(stream, " - SOAP document/literal style\n");
1206
{ if ((*op2)->input->use == literal)
1207
fprintf(stream, " - SOAP RPC literal style\n");
1208
else if ((*op2)->input->encodingStyle)
1209
fprintf(stream, " - SOAP RPC encodingStyle=\"%s\"\n", (*op2)->input->encodingStyle);
1211
fprintf(stream, " - SOAP RPC encoded\n");
1214
{ if ((*op2)->input->use != (*op2)->output->use)
1215
{ if ((*op2)->output->use == literal)
1216
fprintf(stream, " - SOAP RPC literal response\n");
1217
else if ((*op2)->output->encodingStyle)
1218
fprintf(stream, " - SOAP RPC response encodingStyle=\"%s\"\n", (*op2)->output->encodingStyle);
1220
fprintf(stream, " - SOAP RPC encoded response\n");
1223
if ((*op2)->soapAction)
1224
{ if (*(*op2)->soapAction)
1225
fprintf(stream, " - SOAP action=\"%s\"\n", (*op2)->soapAction);
1227
for (vector<Message*>::const_iterator message = (*op2)->fault.begin(); message != (*op2)->fault.end(); ++message)
1228
{ if ((*message)->use == literal)
1229
{ for (vector<wsdl__part>::const_iterator part = (*message)->message->part.begin(); part != (*message)->message->part.end(); ++part)
1230
{ if ((*part).element)
1231
fprintf(stream, " - SOAP Fault: %s (literal)\n", (*part).element);
1232
else if ((*part).name && (*part).type)
1233
fprintf(stream, " - SOAP Fault: %s (literal)\n", (*part).name);
1236
else if ((*message)->message && (*message)->message->name)
1237
fprintf(stream, " - SOAP Fault: %s\n", (*message)->name);
1239
if (!(*op2)->input->header.empty())
1240
fprintf(stream, " - Request message has mandatory header part(s):\n");
1241
for (vector<soap__header>::const_iterator inputheader = (*op2)->input->header.begin(); inputheader != (*op2)->input->header.end(); ++inputheader)
1242
{ if ((*inputheader).part)
1243
{ if ((*inputheader).use == encoded && (*inputheader).namespace_)
1244
fprintf(stream, " - %s\n", types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
1245
else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
1246
fprintf(stream, " - %s\n", types.aname(NULL, NULL, (*inputheader).partPtr()->element));
1249
if ((*op2)->input->multipartRelated)
1251
fprintf(stream, " - Request message has MIME multipart/related attachments:\n");
1252
for (vector<mime__part>::const_iterator part = (*op2)->input->multipartRelated->part.begin(); part != (*op2)->input->multipartRelated->part.end(); ++part)
1253
{ if ((*part).soap__body_)
1254
{ fprintf(stream, " -# MIME attachment with SOAP Body and mandatory header part(s):\n");
1255
for (vector<soap__header>::const_iterator header = (*part).soap__header_.begin(); header != (*part).soap__header_.end(); ++header)
1256
{ if ((*header).part)
1257
{ if ((*header).use == encoded && (*header).namespace_)
1258
fprintf(stream, " - %s\n", types.aname(NULL, (*header).namespace_, (*header).part));
1259
else if ((*header).partPtr() && (*header).partPtr()->element)
1260
fprintf(stream, " - %s\n", types.aname(NULL, NULL, (*header).partPtr()->element));
1265
{ fprintf(stream, " -# MIME attachment %d:\n", k++);
1266
for (vector<mime__content>::const_iterator content = (*part).content.begin(); content != (*part).content.end(); ++content)
1267
{ fprintf(stream, " -");
1268
if ((*content).part)
1269
{ fprintf(stream, " part=\"");
1270
text((*content).part);
1271
fprintf(stream, "\"");
1273
if ((*content).type)
1274
{ fprintf(stream, " type=\"");
1275
text((*content).type);
1276
fprintf(stream, "\"");
1278
fprintf(stream, "\n");
1283
if ((*op2)->input->layout)
1284
fprintf(stream, " - Request message has DIME attachments in compliance with %s\n", (*op2)->input->layout);
1286
{ if (!(*op2)->output->header.empty())
1287
fprintf(stream, " - Response message has mandatory header part(s):\n");
1288
for (vector<soap__header>::const_iterator outputheader = (*op2)->output->header.begin(); outputheader != (*op2)->output->header.end(); ++outputheader)
1289
{ if ((*outputheader).part)
1290
{ if ((*outputheader).use == encoded && (*outputheader).namespace_)
1291
fprintf(stream, " - %s\n", types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
1292
else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
1293
fprintf(stream, " - %s\n", types.aname(NULL, NULL, (*outputheader).partPtr()->element));
1297
if ((*op2)->output && (*op2)->output_name && (*op2)->output->multipartRelated)
1299
fprintf(stream, " - Response message has MIME multipart/related attachments\n");
1300
for (vector<mime__part>::const_iterator part = (*op2)->output->multipartRelated->part.begin(); part != (*op2)->output->multipartRelated->part.end(); ++part)
1301
{ if ((*part).soap__body_)
1302
{ fprintf(stream, " -# MIME attachment with SOAP Body and mandatory header part(s):\n");
1303
for (vector<soap__header>::const_iterator header = (*part).soap__header_.begin(); header != (*part).soap__header_.end(); ++header)
1304
{ if ((*header).part)
1305
{ if ((*header).use == encoded && (*header).namespace_)
1306
fprintf(stream, " - %s\n", types.aname(NULL, (*header).namespace_, (*header).part));
1307
else if ((*header).partPtr() && (*header).partPtr()->element)
1308
fprintf(stream, " - %s\n", types.aname(NULL, NULL, (*header).partPtr()->element));
1313
{ fprintf(stream, " -# MIME attachment %d:\n", k++);
1314
for (vector<mime__content>::const_iterator content = (*part).content.begin(); content != (*part).content.end(); ++content)
1315
{ fprintf(stream, " -");
1316
if ((*content).part)
1317
{ fprintf(stream, " part=\"");
1318
text((*content).part);
1319
fprintf(stream, "\"");
1321
if ((*content).type)
1322
{ fprintf(stream, " type=\"");
1323
text((*content).type);
1324
fprintf(stream, "\"");
1326
fprintf(stream, "\n");
1331
if ((*op2)->output && (*op2)->output_name && (*op2)->output->layout)
1332
fprintf(stream, " - Response message has DIME attachments in compliance with %s\n", (*op2)->output->layout);
1333
fprintf(stream, "\nC stub function (defined in soapClient.c[pp] generated by soapcpp2):\n@code\n int soap_call_%s(\n struct soap *soap,\n NULL, // char *endpoint = NULL selects default endpoint for this operation\n NULL, // char *action = NULL selects default action for this operation\n // request parameters:", (*op2)->input_name);
1334
(*op2)->input->generate(types, ",", false, false, false);
1335
fprintf(stream, "\n // response parameters:");
1336
if ((*op2)->output && (*op2)->output_name)
1338
{ if ((*op2)->style == document)
1339
{ // Shortcut: do not generate wrapper struct
1340
(*op2)->output->generate(types, "", false, false, true);
1342
else if ((*(*op2)->output->message->part.begin()).name)
1343
{ fprintf(stream, "\n");
1344
fprintf(stream, anonymous ? anonformat : paraformat, types.tname(NULL, NULL, (*(*op2)->output->message->part.begin()).type), cflag ? "*" : "&", types.aname(NULL, NULL, (*(*op2)->output->message->part.begin()).name), "");
1348
fprintf(stream, "\n struct %s%s", (*op2)->output_name, cflag ? "*" : "&");
1350
fprintf(stream, "\n );\n@endcode\n\nC server function (called from the service dispatcher defined in soapServer.c[pp]):\n@code\n int %s(\n struct soap *soap,\n // request parameters:", (*op2)->input_name);
1351
(*op2)->input->generate(types, ",", false, false, false);
1352
fprintf(stream, "\n // response parameters:");
1353
if ((*op2)->output && (*op2)->output_name)
1355
{ if ((*op2)->style == document)
1356
{ // Shortcut: do not generate wrapper struct
1357
(*op2)->output->generate(types, "", false, false, true);
1359
else if ((*(*op2)->output->message->part.begin()).name)
1360
{ fprintf(stream, "\n");
1361
fprintf(stream, anonymous ? anonformat : paraformat, types.tname(NULL, NULL, (*(*op2)->output->message->part.begin()).type), cflag ? "*" : "&", types.aname(NULL, NULL, (*(*op2)->output->message->part.begin()).name), "");
1365
fprintf(stream, "\n struct %s%s", (*op2)->output_name, cflag ? "*" : "&");
1367
fprintf(stream, "\n );\n@endcode\n\n");
1369
{ fprintf(stream, "C++ proxy class (defined in soap%sProxy.h):\n", name);
1370
fprintf(stream, " class %s;\n\n", name);
1371
fprintf(stream, "Note: use soapcpp2 option '-i' to generate improved proxy and service classes;\n\n");
1373
fprintf(stream, "*/\n\n");
1374
(*op2)->generate(types);
1379
////////////////////////////////////////////////////////////////////////////////
1381
// Operation methods
1383
////////////////////////////////////////////////////////////////////////////////
1385
void Operation::generate(Types &types)
1386
{ bool flag = false, anonymous = ((style != document) && parameterOrder != NULL);
1387
const char *method_name = strstr(input_name + 1, "__") + 2;
1389
method_name = input_name;
1390
if (style == document)
1391
fprintf(stream, serviceformat, prefix, "method-style", method_name, "document");
1393
fprintf(stream, serviceformat, prefix, "method-style", method_name, "rpc");
1394
if (input->use == literal)
1395
fprintf(stream, serviceformat, prefix, "method-encoding", method_name, "literal");
1396
else if (input->encodingStyle)
1397
fprintf(stream, serviceformat, prefix, "method-encoding", method_name, input->encodingStyle);
1399
fprintf(stream, serviceformat, prefix, "method-encoding", method_name, "encoded");
1401
{ if (input->use != output->use)
1402
{ if (output->use == literal)
1403
fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, "literal");
1404
else if (output->encodingStyle)
1405
fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, output->encodingStyle);
1407
fprintf(stream, serviceformat, prefix, "method-response-encoding", method_name, "encoded");
1409
if (style == rpc && input->URI && output->URI && strcmp(input->URI, output->URI))
1410
fprintf(stream, schemaformat, types.nsprefix(NULL, output->URI), "namespace", output->URI);
1414
fprintf(stream, serviceformat, prefix, "method-action", method_name, soapAction);
1416
fprintf(stream, serviceformat, prefix, "method-action", method_name, "\"\"");
1418
for (vector<Message*>::const_iterator message = fault.begin(); message != fault.end(); ++message)
1419
{ if ((*message)->use == literal)
1420
{ for (vector<wsdl__part>::const_iterator part = (*message)->message->part.begin(); part != (*message)->message->part.end(); ++part)
1421
{ if ((*part).element)
1422
fprintf(stream, serviceformat, prefix, "method-fault", method_name, types.aname(NULL, NULL, (*part).element));
1423
else if ((*part).type)
1424
fprintf(stream, serviceformat, prefix, "method-fault", method_name, types.aname(NULL, (*message)->URI, (*part).name));
1428
{ if ((*message)->message && (*message)->message->name)
1429
fprintf(stream, serviceformat, prefix, "method-fault", method_name, (*message)->name);
1432
if (input->multipartRelated)
1433
{ for (vector<mime__part>::const_iterator inputmime = input->multipartRelated->part.begin(); inputmime != input->multipartRelated->part.end(); ++inputmime)
1434
{ for (vector<soap__header>::const_iterator inputheader = (*inputmime).soap__header_.begin(); inputheader != (*inputmime).soap__header_.end(); ++inputheader)
1435
{ if ((*inputheader).part)
1436
{ if ((*inputheader).use == encoded && (*inputheader).namespace_)
1437
fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
1438
else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
1439
fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, NULL, (*inputheader).partPtr()->element));
1442
for (vector<mime__content>::const_iterator content = (*inputmime).content.begin(); content != (*inputmime).content.end(); ++content)
1443
if ((*content).type)
1444
fprintf(stream, serviceformat, prefix, "method-input-mime-type", method_name, (*content).type);
1447
// TODO: add headerfault directives
1448
for (vector<soap__header>::const_iterator inputheader = input->header.begin(); inputheader != input->header.end(); ++inputheader)
1449
{ if ((*inputheader).part)
1450
{ if ((*inputheader).use == encoded && (*inputheader).namespace_)
1451
fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, (*inputheader).namespace_, (*inputheader).part));
1452
else if ((*inputheader).partPtr() && (*inputheader).partPtr()->element)
1453
fprintf(stream, serviceformat, prefix, "method-input-header-part", method_name, types.aname(NULL, NULL, (*inputheader).partPtr()->element));
1457
{ if (output->multipartRelated)
1458
{ for (vector<mime__part>::const_iterator outputmime = output->multipartRelated->part.begin(); outputmime != output->multipartRelated->part.end(); ++outputmime)
1459
{ for (vector<soap__header>::const_iterator outputheader = (*outputmime).soap__header_.begin(); outputheader != (*outputmime).soap__header_.end(); ++outputheader)
1460
{ if ((*outputheader).part)
1461
{ if ((*outputheader).use == encoded && (*outputheader).namespace_)
1462
fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
1463
else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
1464
fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, NULL, (*outputheader).partPtr()->element));
1467
for (vector<mime__content>::const_iterator content = (*outputmime).content.begin(); content != (*outputmime).content.end(); ++content)
1468
if ((*content).type)
1469
fprintf(stream, serviceformat, prefix, "method-output-mime-type", method_name, (*content).type);
1472
for (vector<soap__header>::const_iterator outputheader = output->header.begin(); outputheader != output->header.end(); ++outputheader)
1473
{ if ((*outputheader).part)
1474
{ if ((*outputheader).use == encoded && (*outputheader).namespace_)
1475
fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, (*outputheader).namespace_, (*outputheader).part));
1476
else if ((*outputheader).partPtr() && (*outputheader).partPtr()->element)
1477
fprintf(stream, serviceformat, prefix, "method-output-header-part", method_name, types.aname(NULL, NULL, (*outputheader).partPtr()->element));
1482
{ if (style == document)
1483
flag = output->message && output->message->part.size() == 1;
1485
flag = output->message && output->use == encoded && output->message->part.size() == 1 && !(*output->message->part.begin()).simpleTypePtr() && !(*output->message->part.begin()).complexTypePtr();
1486
if (flag && input->message && (*output->message->part.begin()).element)
1487
for (vector<wsdl__part>::const_iterator part = input->message->part.begin(); part != input->message->part.end(); ++part)
1488
if ((*part).element && !strcmp((*part).element, (*output->message->part.begin()).element))
1491
fprintf(stream, "int %s(", input_name);
1492
input->generate(types, ",", anonymous, true, false);
1495
{ if (style == document)
1496
{ // Shortcut: do not generate wrapper struct
1497
output->generate(types, "", false, true, true);
1499
else if ((*output->message->part.begin()).name)
1500
{ fprintf(stream, "\n");
1501
fprintf(stream, anonymous ? anonformat : paraformat, types.tname(NULL, NULL, (*output->message->part.begin()).type), cflag ? "*" : "&", types.aname(NULL, NULL, (*output->message->part.begin()).name), "");
1502
fprintf(stream, "\t///< Response parameter");
1506
{ fprintf(stream, "\n struct %-28s%s", output_name, cflag ? "*" : "&");
1507
fprintf(stream, "\t///< Response struct parameter");
1509
fprintf(stream, "\n);\n");
1512
fprintf(stream, "\n void\t///< One-way message: no response parameter\n);\n");
1515
////////////////////////////////////////////////////////////////////////////////
1519
////////////////////////////////////////////////////////////////////////////////
1521
void Message::generate(Types &types, const char *sep, bool anonymous, bool remark, bool response)
1523
{ for (vector<wsdl__part>::const_iterator part = message->part.begin(); part != message->part.end(); ++part)
1524
{ if (!(*part).name)
1525
fprintf(stderr, "Error: no part name in message '%s'\n", message->name?message->name:"");
1526
else if (!body_parts || soap_strsearch(body_parts, (*part).name))
1527
{ if (remark && (*part).documentation)
1528
comment("", (*part).name, "parameter", (*part).documentation);
1530
fprintf(stream, "\n");
1531
if ((*part).element)
1532
{ if ((*part).elementPtr())
1533
{ const char *name, *type, *URI, *prefix = NULL;
1534
name = (*part).elementPtr()->name;
1535
/* comment out to use a type that refers to an element defined with typedef */
1536
if ((*part).elementPtr()->type)
1537
type = (*part).elementPtr()->type;
1542
if ((*part).elementPtr()->schemaPtr())
1543
URI = (*part).elementPtr()->schemaPtr()->targetNamespace;
1547
{ const char *t = types.tname(prefix, URI, type);
1548
bool flag = (strchr(t, '*') && strcmp(t, "char*") && strcmp(t, "char *"));
1549
fprintf(stream, anonymous ? anonformat : paraformat, t, flag ? " " : cflag ? "*" : "&", types.aname(NULL, URI, name), sep);
1551
fprintf(stream, "\t///< Response parameter");
1554
{ fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, prefix, URI, type), " ", types.aname(NULL, URI, name), sep);
1555
if (remark && *sep == ',')
1556
fprintf(stream, "\t///< Request parameter");
1560
{ fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, NULL, NULL, (*part).element), " ", types.aname(NULL, NULL, (*part).element), sep);
1562
fprintf(stream, "\t///< TODO: Check element type (imported type)");
1565
else if ((*part).type)
1566
{ if (use == literal)
1567
fprintf(stderr, "Warning: part '%s' uses literal style and should refer to an element rather than a type\n", (*part).name);
1569
{ const char *t = types.tname(NULL, NULL, (*part).type);
1570
bool flag = (strchr(t, '*') && strcmp(t, "char*") && strcmp(t, "char *"));
1571
fprintf(stream, anonymous ? anonformat : paraformat, t, flag ? " " : cflag ? "*" : "&", types.aname(NULL, NULL, (*part).name), sep);
1573
fprintf(stream, "\t///< Response parameter");
1576
{ fprintf(stream, anonymous ? anonformat : paraformat, types.pname(false, NULL, NULL, (*part).type), " ", types.aname(NULL, NULL, (*part).name), sep);
1577
if (remark && *sep == ',')
1578
fprintf(stream, "\t///< Request parameter");
1582
fprintf(stderr, "Error: no wsdl:definitions/message/part/@type in part '%s'\n", (*part).name);
1587
fprintf(stderr, "Error: no wsdl:definitions/message\n");
1590
////////////////////////////////////////////////////////////////////////////////
1594
////////////////////////////////////////////////////////////////////////////////
1596
static void comment(const char *start, const char *middle, const char *end, const char *text)
1598
{ if (strchr(text, '\r') || strchr(text, '\n'))
1599
fprintf(stream, "\n/** %s %s %s documentation:\n%s\n*/\n\n", start, middle, end, text);
1601
fprintf(stream, "\n/// %s %s %s: %s\n", start, middle, end, text);
1605
static void page(const char *page, const char *title, const char *text)
1607
fprintf(stream, "\n@page %s%s \"%s\"\n", page, title, text);
1609
fprintf(stream, "\n@page %s%s\n", page, title);
1612
static void section(const char *section, const char *title, const char *text)
1614
fprintf(stream, "\n@section %s%s \"%s\"\n", section, title, text);
1616
fprintf(stream, "\n@section %s%s\n", section, title);
1619
static void banner(const char *text)
1621
fprintf(stream, "\n/");
1622
for (i = 0; i < 78; i++)
1624
fprintf(stream, "\\\n *%76s*\n * %-75s*\n *%76s*\n\\", "", text, "");
1625
for (i = 0; i < 78; i++)
1627
fprintf(stream, "/\n\n");
1629
fprintf(stderr, "\n---- %s ----\n\n", text);
1633
{ time_t t = time(NULL), *p = &t;
1636
strftime(tmp, 256, "%Y-%m-%d %H:%M:%S GMT", gmtime(p));
1637
fprintf(stream, "/* %s\n Generated by wsdl2h "VERSION" from ", outfile?outfile:"");
1639
{ for (i = 0; i < infiles; i++)
1640
fprintf(stream, "%s ", infile[i]);
1643
fprintf(stream, "(stdin) ");
1644
fprintf(stream, "and %s\n %s\n Copyright (C) 2001-2006 Robert van Engelen, Genivia Inc. All Rights Reserved.\n This part of the software is released under one of the following licenses:\n GPL or Genivia's license for commercial use.\n*/\n\n", mapfile, tmp);
1647
static void text(const char *text)
1648
{ const char *s = text;
1674
fputc('\n', stream);