comparison GEMBASSY-1.0.3/gsoap/wsdl/types.cpp @ 0:8300eb051bea draft

Initial upload
author ktnyt
date Fri, 26 Jun 2015 05:19:29 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8300eb051bea
1 /*
2 types.cpp
3
4 Generate gSOAP types from XML schemas (e.g. embedded in WSDL).
5
6 --------------------------------------------------------------------------------
7 gSOAP XML Web services tools
8 Copyright (C) 2001-2013, Robert van Engelen, Genivia Inc. All Rights Reserved.
9 This software is released under one of the following licenses:
10 GPL or Genivia's license for commercial use.
11 --------------------------------------------------------------------------------
12 GPL license.
13
14 This program is free software; you can redistribute it and/or modify it under
15 the terms of the GNU General Public License as published by the Free Software
16 Foundation; either version 2 of the License, or (at your option) any later
17 version.
18
19 This program is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 PARTICULAR PURPOSE. See the GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
25 Place, Suite 330, Boston, MA 02111-1307 USA
26
27 Author contact information:
28 engelen@genivia.com / engelen@acm.org
29 --------------------------------------------------------------------------------
30 A commercial use license is available from Genivia, Inc., contact@genivia.com
31 --------------------------------------------------------------------------------
32
33 */
34
35 #include "types.h"
36
37 static char *getline(char *s, size_t n, FILE *fd);
38 static const char *nonblank(const char *s);
39 static const char *fill(char *t, int n, const char *s, int e);
40 static const char *utf8(char *t, const char *s);
41 static const char *cstring(const char *s);
42 static const char *xstring(const char *s);
43 static bool is_integer(const char *s);
44 static LONG64 to_integer(const char *s);
45 static void documentation(const char *text);
46 static void operations(const char *t);
47
48 static int comment_nest = 0; /* keep track of block comments to avoid nesting */
49
50 ////////////////////////////////////////////////////////////////////////////////
51 //
52 // Keywords and reserved words
53 //
54 ////////////////////////////////////////////////////////////////////////////////
55
56 static const char *keywords[] =
57 { "and",
58 "asm",
59 "auto",
60 "bool",
61 "break",
62 "case",
63 "catch",
64 "char",
65 "class",
66 "const",
67 "const_cast",
68 "continue",
69 "default",
70 "delete",
71 "do",
72 "double",
73 "dynamic_cast",
74 "else",
75 "enum",
76 "errno",
77 "explicit",
78 "export",
79 "extern",
80 "false",
81 "FILE",
82 "float",
83 "for",
84 "friend",
85 "goto",
86 "if",
87 "inline",
88 "int",
89 "interface",
90 "long",
91 "LONG64",
92 "max",
93 "min",
94 "mustUnderstand",
95 "mutable",
96 "namespace",
97 "new",
98 "not",
99 "NULL",
100 "operator",
101 "or",
102 "private",
103 "protected",
104 "public",
105 "_QName",
106 "register",
107 "reinterpret_cast",
108 "restrict",
109 "return",
110 "short",
111 "signed",
112 "size_t",
113 "sizeof",
114 "soap",
115 "static",
116 "static_cast",
117 "struct",
118 "switch",
119 "template",
120 "this",
121 "throw",
122 "time_t",
123 "true",
124 "typedef",
125 "typeid",
126 "typeof",
127 "typename",
128 "ULONG64",
129 "union",
130 "unsigned",
131 "using",
132 "virtual",
133 "void",
134 "volatile",
135 "wchar_t",
136 "while",
137 "XML",
138 "_XML",
139 "xor",
140 };
141
142 ////////////////////////////////////////////////////////////////////////////////
143 //
144 // Types methods
145 //
146 ////////////////////////////////////////////////////////////////////////////////
147
148 Types::Types()
149 { init();
150 }
151
152 int Types::read(const char *file)
153 { FILE *fd;
154 char buf[1024], xsd[1024], def[1024], use[1024], ptr[1024], uri[1024];
155 const char *s;
156 short copy = 0;
157 strcpy(buf, file);
158 fd = fopen(buf, "r");
159 if (!fd && import_path)
160 { strcpy(buf, import_path);
161 strcat(buf, "/");
162 strcat(buf, file);
163 fd = fopen(buf, "r");
164 }
165 if (!fd)
166 { fprintf(stderr, "Cannot open file '%s'\n", buf);
167 return SOAP_EOF;
168 }
169 fprintf(stderr, "Reading type definitions from type map file '%s'\n", buf);
170 while (getline(buf, sizeof(buf), fd))
171 { s = buf;
172 if (copy)
173 { if (*s == ']')
174 copy = 0;
175 else
176 fprintf(stream, "%s\n", buf);
177 }
178 else if (*s == '[')
179 copy = 1;
180 else if (*s == '<')
181 { s = fill(uri, sizeof(uri), s+1, -1);
182 infile[infiles++] = estrdup(uri);
183 if (infiles >= MAXINFILES)
184 { fprintf(stderr, "wsdl2h: too many files\n");
185 exit(1);
186 }
187 }
188 else if (*s == '>')
189 { s = fill(uri, sizeof(uri), s+1, -1);
190 if (!outfile)
191 { outfile = estrdup(uri);
192 stream = fopen(outfile, "w");
193 if (!stream)
194 { fprintf(stderr, "Cannot write to %s\n", outfile);
195 exit(1);
196 }
197 if (cppnamespace)
198 fprintf(stream, "namespace %s {\n", cppnamespace);
199 fprintf(stderr, "Saving %s\n\n", outfile);
200 }
201 }
202 else if (*s && *s != '#')
203 { s = fill(xsd, sizeof(xsd), s, '=');
204 if (strstr(xsd, "__"))
205 { if (s && *s == '=')
206 { s = fill(use, sizeof(use), s+1, '|');
207 if (*xsd && *use)
208 { s = estrdup(xsd);
209 eqvtypemap[s] = estrdup(use);
210 }
211 }
212 else
213 { s = fill(def, sizeof(def), s, '|');
214 s = fill(use, sizeof(use), s, '|');
215 s = fill(ptr, sizeof(ptr), s, '|');
216 if (*xsd)
217 { s = estrdup(xsd);
218 if (*def == '$')
219 { const char *t = modtypemap[s];
220 if (t)
221 { char *r = (char*)emalloc(strlen(t) + strlen(def) + 1);
222 strcpy(r, t);
223 strcat(r, def);
224 free((void*)modtypemap[s]);
225 modtypemap[s] = r;
226 }
227 else
228 modtypemap[s] = estrdup(def);
229 }
230 else
231 { if (*def)
232 { if (strcmp(def, "..."))
233 deftypemap[s] = estrdup(def);
234 }
235 else
236 deftypemap[s] = "";
237 if (*use)
238 usetypemap[s] = estrdupf(use);
239 else
240 usetypemap[s] = estrdupf(xsd);
241 if (*ptr)
242 ptrtypemap[s] = estrdupf(ptr);
243 }
244 }
245 }
246 }
247 else if (*xsd)
248 { s = fill(uri, sizeof(uri), s, 0);
249 if (uri[0] == '"')
250 { uri[strlen(uri) - 1] = '\0';
251 nsprefix(xsd, estrdup(uri + 1));
252 }
253 else if (uri[0] == '<')
254 { uri[strlen(uri) - 1] = '\0';
255 char *s = estrdup(uri + 1);
256 nsprefix(xsd, s);
257 exturis.insert(s);
258 }
259 else
260 nsprefix(xsd, estrdup(uri));
261 }
262 }
263 }
264 fclose(fd);
265 return SOAP_OK;
266 }
267
268 void Types::init()
269 { snum = 1;
270 unum = 1;
271 gnum = 1;
272 with_union = false;
273 fake_union = false;
274 knames.insert(keywords, keywords + sizeof(keywords)/sizeof(char*));
275 if (cflag)
276 { deftypemap["xsd__ur_type"] = "";
277 if (dflag)
278 { usetypemap["xsd__ur_type"] = "xsd__anyType";
279 ptrtypemap["xsd__ur_type"] = "xsd__anyType*";
280 }
281 else
282 { usetypemap["xsd__ur_type"] = "_XML";
283 ptrtypemap["xsd__ur_type"] = "_XML";
284 }
285 }
286 else
287 { deftypemap["xsd__ur_type"] = "class xsd__ur_type { _XML __item; struct soap *soap; };";
288 usetypemap["xsd__ur_type"] = "xsd__ur_type";
289 }
290 if (cflag)
291 { deftypemap["xsd__anyType"] = "";
292 if (dflag)
293 { usetypemap["xsd__anyType"] = "xsd__anyType";
294 ptrtypemap["xsd__anyType"] = "xsd__anyType*";
295 }
296 else
297 { usetypemap["xsd__anyType"] = "_XML";
298 ptrtypemap["xsd__anyType"] = "_XML";
299 }
300 }
301 else
302 { if (dflag)
303 { deftypemap["xsd__anyType"] = "";
304 usetypemap["xsd__anyType"] = "xsd__anyType";
305 ptrtypemap["xsd__anyType"] = "xsd__anyType*";
306 }
307 else
308 { deftypemap["xsd__anyType"] = "class xsd__anyType { _XML __item; struct soap *soap; };";
309 usetypemap["xsd__anyType"] = "xsd__anyType*";
310 }
311 }
312 deftypemap["xsd__any"] = "";
313 if (dflag)
314 { usetypemap["xsd__any"] = "xsd__anyType";
315 ptrtypemap["xsd__any"] = "xsd__anyType*";
316 }
317 else
318 { usetypemap["xsd__any"] = "_XML";
319 ptrtypemap["xsd__any"] = "_XML";
320 }
321 deftypemap["xsd__anyAttribute"] = "";
322 if (dflag)
323 { usetypemap["xsd__anyAttribute"] = "xsd__anyAttribute";
324 ptrtypemap["xsd__anyAttribute"] = "xsd__anyAttribute*";
325 }
326 else
327 { usetypemap["xsd__anyAttribute"] = "_XML";
328 ptrtypemap["xsd__anyAttribute"] = "_XML";
329 }
330 if (cflag)
331 { deftypemap["xsd__base64Binary"] = "struct xsd__base64Binary\n{\tunsigned char *__ptr;\n\tint __size;\n\tchar *id, *type, *options; // NOTE: non-NULL for DIMEM/MIME/MTOM XOP attachments only\n};";
332 usetypemap["xsd__base64Binary"] = "struct xsd__base64Binary";
333 }
334 else
335 { deftypemap["xsd__base64Binary"] = "class xsd__base64Binary\n{\tunsigned char *__ptr;\n\tint __size;\n\tchar *id, *type, *options; // NOTE: non-NULL for DIMEM/MIME/MTOM XOP attachments only\n\tstruct soap *soap;\n};";
336 usetypemap["xsd__base64Binary"] = "xsd__base64Binary";
337 }
338 if (cflag)
339 { if (eflag)
340 deftypemap["xsd__boolean"] = "enum xsd__boolean { false_, true_ };";
341 else
342 deftypemap["xsd__boolean"] = "enum xsd__boolean { xsd__boolean__false_, xsd__boolean__true_ };";
343 usetypemap["xsd__boolean"] = "enum xsd__boolean";
344 }
345 else
346 { deftypemap["xsd__boolean"] = "";
347 usetypemap["xsd__boolean"] = "bool";
348 }
349 deftypemap["xsd__byte"] = "typedef char xsd__byte;";
350 usetypemap["xsd__byte"] = "xsd__byte";
351 deftypemap["xsd__dateTime"] = "";
352 usetypemap["xsd__dateTime"] = "time_t";
353 deftypemap["xsd__double"] = "";
354 usetypemap["xsd__double"] = "double";
355 deftypemap["xsd__float"] = "";
356 usetypemap["xsd__float"] = "float";
357 if (cflag)
358 { deftypemap["xsd__hexBinary"] = "struct xsd__hexBinary { unsigned char *__ptr; int __size; };";
359 usetypemap["xsd__hexBinary"] = "struct xsd__hexBinary";
360 }
361 else
362 { deftypemap["xsd__hexBinary"] = "class xsd__hexBinary { unsigned char *__ptr; int __size; };";
363 usetypemap["xsd__hexBinary"] = "xsd__hexBinary";
364 }
365 deftypemap["xsd__int"] = "";
366 usetypemap["xsd__int"] = "int";
367 deftypemap["xsd__long"] = "";
368 usetypemap["xsd__long"] = "LONG64";
369 deftypemap["xsd__short"] = "";
370 usetypemap["xsd__short"] = "short";
371 if (cflag || sflag)
372 { deftypemap["xsd__string"] = "";
373 usetypemap["xsd__string"] = "char*";
374 }
375 else
376 { deftypemap["xsd__string"] = "";
377 usetypemap["xsd__string"] = "std::string";
378 }
379 if (cflag || sflag)
380 { deftypemap["xsd__QName"] = "";
381 usetypemap["xsd__QName"] = "_QName";
382 ptrtypemap["xsd__QName"] = "_QName";
383 }
384 else
385 { deftypemap["xsd__QName"] = "typedef std::string xsd__QName;";
386 usetypemap["xsd__QName"] = "xsd__QName";
387 }
388 deftypemap["xsd__unsignedByte"] = "typedef unsigned char xsd__unsignedByte;";
389 usetypemap["xsd__unsignedByte"] = "xsd__unsignedByte";
390 deftypemap["xsd__unsignedInt"] = "";
391 usetypemap["xsd__unsignedInt"] = "unsigned int";
392 deftypemap["xsd__unsignedLong"] = "";
393 usetypemap["xsd__unsignedLong"] = "ULONG64";
394 deftypemap["xsd__unsignedShort"] = "";
395 usetypemap["xsd__unsignedShort"] = "unsigned short";
396 if (cflag)
397 { deftypemap["SOAP_ENC__base64Binary"] = "struct SOAP_ENC__base64Binary { unsigned char *__ptr; int __size; };";
398 usetypemap["SOAP_ENC__base64Binary"] = "struct SOAP_ENC__base64Binary";
399 deftypemap["SOAP_ENC__base64"] = "struct SOAP_ENC__base64 { unsigned char *__ptr; int __size; };";
400 usetypemap["SOAP_ENC__base64"] = "struct SOAP_ENC__base64";
401 }
402 else
403 { deftypemap["SOAP_ENC__base64Binary"] = "class SOAP_ENC__base64Binary { unsigned char *__ptr; int __size; };";
404 usetypemap["SOAP_ENC__base64Binary"] = "SOAP_ENC__base64Binary";
405 deftypemap["SOAP_ENC__base64"] = "class SOAP_ENC__base64 { unsigned char *__ptr; int __size; };";
406 usetypemap["SOAP_ENC__base64"] = "SOAP_ENC__base64";
407 }
408 if (cflag)
409 { deftypemap["SOAP_ENC__boolean"] = "enum SOAP_ENC__boolean { false_, true_ };";
410 usetypemap["SOAP_ENC__boolean"] = "enum SOAP_ENC__boolean";
411 }
412 else
413 { deftypemap["SOAP_ENC__boolean"] = "typedef bool SOAP_ENC__boolean;";
414 usetypemap["SOAP_ENC__boolean"] = "SOAP_ENC__boolean";
415 }
416 deftypemap["SOAP_ENC__byte"] = "typedef char SOAP_ENC__byte;";
417 usetypemap["SOAP_ENC__byte"] = "SOAP_ENC__byte";
418 deftypemap["SOAP_ENC__dateTime"] = "typedef time_t SOAP_ENC__dateTime;";
419 usetypemap["SOAP_ENC__dateTime"] = "SOAP_ENC__dateTime";
420 deftypemap["SOAP_ENC__double"] = "typedef double SOAP_ENC__double;";
421 usetypemap["SOAP_ENC__double"] = "SOAP_ENC__double";
422 deftypemap["SOAP_ENC__float"] = "typedef float SOAP_ENC__float";
423 usetypemap["SOAP_ENC__float"] = "SOAP_ENC__float";
424 if (cflag)
425 { deftypemap["SOAP_ENC__hexBinary"] = "struct SOAP_ENC__hexBinary { unsigned char *__ptr; int __size; };";
426 usetypemap["SOAP_ENC__hexBinary"] = "struct SOAP_ENC__hexBinary";
427 }
428 else
429 { deftypemap["SOAP_ENC__hexBinary"] = "class SOAP_ENC__hexBinary { unsigned char *__ptr; int __size; };";
430 usetypemap["SOAP_ENC__hexBinary"] = "SOAP_ENC__hexBinary";
431 }
432 deftypemap["SOAP_ENC__int"] = "typedef int SOAP_ENC__int;";
433 usetypemap["SOAP_ENC__int"] = "SOAP_ENC__int";
434 deftypemap["SOAP_ENC__long"] = "typedef LONG64 SOAP_ENC__long;";
435 usetypemap["SOAP_ENC__long"] = "SOAP_ENC__long";
436 deftypemap["SOAP_ENC__short"] = "typedef short SOAP_ENC__short;";
437 usetypemap["SOAP_ENC__short"] = "SOAP_ENC__short";
438 if (cflag || sflag)
439 { deftypemap["SOAP_ENC__string"] = "";
440 usetypemap["SOAP_ENC__string"] = "char*";
441 }
442 else
443 { deftypemap["SOAP_ENC__string"] = "";
444 usetypemap["SOAP_ENC__string"] = "std::string";
445 }
446 deftypemap["SOAP_ENC__unsignedByte"] = "typedef unsigned char SOAP_ENC__unsignedByte;";
447 usetypemap["SOAP_ENC__unsignedByte"] = "SOAP_ENC__unsignedByte";
448 deftypemap["SOAP_ENC__unsignedInt"] = "typedef unsigned int SOAP_ENC__unsignedInt;";
449 usetypemap["SOAP_ENC__unsignedInt"] = "SOAP_ENC__unsignedInt";
450 deftypemap["SOAP_ENC__unsignedLong"] = "typedef ULONG64 SOAP_ENC__unsignedLong;";
451 usetypemap["SOAP_ENC__unsignedLong"] = "SOAP_ENC__unsignedLong";
452 deftypemap["SOAP_ENC__unsignedShort"] = "typedef unsigned short SOAP_ENC__unsignedShort;";
453 usetypemap["SOAP_ENC__unsignedShort"] = "SOAP_ENC__unsignedShort";
454 deftypemap["SOAP_ENC__Array"] = "";
455 usetypemap["SOAP_ENC__Array"] = "struct { _XML *__ptr; int __size; }";
456 deftypemap["_SOAP_ENC__arrayType"] = "";
457 deftypemap["SOAP_ENV__Header"] = "";
458 usetypemap["SOAP_ENV__Header"] = "struct SOAP_ENV__Header";
459 deftypemap["_SOAP_ENV__mustUnderstand"] = "";
460 if (cflag || sflag)
461 usetypemap["_SOAP_ENV__mustUnderstand"] = "char*";
462 else
463 usetypemap["_SOAP_ENV__mustUnderstand"] = "std::string";
464 deftypemap["SOAP_ENV__Fault"] = "";
465 usetypemap["SOAP_ENV__Fault"] = "struct SOAP_ENV__Fault";
466 deftypemap["SOAP_ENV__detail"] = "";
467 usetypemap["SOAP_ENV__detail"] = "struct SOAP_ENV__Detail";
468 deftypemap["SOAP_ENV__Detail"] = "";
469 usetypemap["SOAP_ENV__Detail"] = "struct SOAP_ENV__Detail";
470 deftypemap["SOAP_ENV__Code"] = "";
471 usetypemap["SOAP_ENV__Code"] = "struct SOAP_ENV__Code";
472 deftypemap["SOAP_ENV__Reason"] = "";
473 usetypemap["SOAP_ENV__Reason"] = "struct SOAP_ENV__Reason";
474 if (read(mapfile))
475 fprintf(stderr, "Problem reading type map file '%s'.\nUsing internal type definitions for %s instead.\n\n", mapfile, cflag?"C":"C++");
476 }
477
478 const char *Types::nsprefix(const char *prefix, const char *URI)
479 { if (URI)
480 { const char *s = uris[URI];
481 if (!s)
482 { size_t n;
483 if (!prefix || !*prefix || *prefix == '_')
484 s = schema_prefix;
485 else
486 s = estrdup(prefix);
487 if (!syms[s])
488 n = syms[s] = 1;
489 else
490 n = ++syms[s];
491 if (n != 1 || !prefix || !*prefix || *prefix == '_')
492 { char *t = (char*)emalloc(strlen(s) + 16);
493 sprintf(t, "%s%lu", s, (unsigned long)n);
494 s = t;
495 }
496 uris[URI] = s;
497 if (vflag)
498 fprintf(stderr, "namespace prefix %s = \"%s\"\n", s, URI);
499 }
500 // if *prefix == '_', then add prefix string to s
501 if (prefix && *prefix == '_')
502 { char *t = (char*)emalloc(strlen(s) + 2);
503 *t = '_';
504 strcpy(t + 1, s);
505 s = t;
506 }
507 return s;
508 }
509 return NULL;
510 }
511
512 const char *Types::prefix(const char *name)
513 { const char *s;
514 char *t;
515 if (*name == '"')
516 { s = strchr(name + 1, '"');
517 t = (char*)emalloc(s - name);
518 strncpy(t, name + 1, s - name - 1);
519 t[s - name - 1] = '\0';
520 return nsprefix(NULL, t);
521 }
522 s = strchr(name, ':');
523 if (s)
524 { t = (char*)emalloc(s - name + 1);
525 strncpy(t, name, s - name);
526 t[s - name] = '\0';
527 return t;
528 }
529 return NULL;
530 }
531
532 const char *Types::uri(const char *name)
533 { const char *s;
534 char *t;
535 if (*name == '"')
536 { s = strchr(name + 1, '"');
537 t = (char*)emalloc(s - name);
538 strncpy(t, name + 1, s - name - 1);
539 t[s - name - 1] = '\0';
540 return t;
541 }
542 s = strchr(name, ':');
543 if (s)
544 { struct Namespace *p = namespaces;
545 if (p)
546 { for (p += 6; p->id; p++)
547 { if (!strncmp(p->id, name, s - name) && !p->id[s - name])
548 { if (p->in && *p->in)
549 return p->in;
550 return p->ns;
551 }
552 }
553 }
554 }
555 return NULL;
556 }
557
558 // Find a C name for a QName. If the name has no qualifier, use URI. Suggest prefix for URI
559 const char *Types::fname(const char *prefix, const char *URI, const char *qname, SetOfString *reserved, enum Lookup lookup, bool isqname)
560 { char buf[1024], *t;
561 const char *p, *s, *name;
562 if (!qname)
563 { fprintf(stream, "// Warning: internal error, no QName in fname()\n");
564 if (vflag)
565 fprintf(stderr, "Internal error, no QName in fname()\n");
566 qname = "?";
567 }
568 name = qname;
569 if (isqname)
570 s = strrchr(name, ':');
571 else
572 s = NULL;
573 if (s)
574 { name = s + 1;
575 if (qname[0] == '"' && qname[1] == '"')
576 s = NULL;
577 else if (*qname == '"')
578 { t = (char*)emalloc(s - qname - 1);
579 strncpy(t, qname + 1, s - qname - 2);
580 t[s - qname - 2] = '\0';
581 URI = t;
582 }
583 else if (!strncmp(qname, "xs:", 3)) // this hack is necessary since the nsmap table defines "xs" for "xsd"
584 { s = "xsd";
585 URI = NULL;
586 }
587 else
588 { t = (char*)emalloc(s - qname + 1);
589 strncpy(t, qname, s - qname);
590 t[s - qname] = '\0';
591 s = t;
592 URI = NULL;
593 }
594 }
595 if (URI)
596 p = nsprefix(prefix, URI);
597 else if (s)
598 p = s;
599 else
600 p = "";
601 s = NULL;
602 if (lookup == LOOKUP)
603 { if (qnames.find(Pair(p,name)) != qnames.end())
604 s = qnames[Pair(p,name)];
605 }
606 if (!s)
607 { t = buf;
608 if (!prefix || *prefix)
609 { s = p;
610 // no longer add '_' when URI != NULL, since nsprefix() will do this
611 if (prefix && *prefix == ':')
612 *t++ = ':';
613 else if (prefix && *prefix == '_')
614 { if (!URI)
615 *t++ = '_';
616 if (prefix[1] == '_') // ensures ns prefix starts with __
617 { strcpy(t, prefix + 1);
618 t += strlen(prefix + 1);
619 }
620 }
621 if (s && *s)
622 { for (; *s; s++)
623 { if (isalnum(*s))
624 *t++ = *s;
625 else if (*s == '-' && s[1] != '-' && s != p)
626 *t++ = '_';
627 else if (*s == '_')
628 { if (s == p)
629 *t++ = '_';
630 else if (!_flag)
631 { strcpy(t, "_USCORE");
632 t += 7;
633 }
634 else
635 { s = utf8(t, s);
636 t += 6;
637 }
638 }
639 else
640 { s = utf8(t, s);
641 t += 6;
642 }
643 }
644 if (!prefix || *prefix != '*')
645 { *t++ = '_';
646 *t++ = '_';
647 }
648 }
649 else if (isdigit(*name))
650 *t++ = '_';
651 }
652 for (s = name; *s; s++)
653 { if (isalnum(*s))
654 *t++ = *s;
655 else if (*s == '-' && s[1] != '-' && s[1] != '\0' && s != name)
656 *t++ = '_';
657 else if (!_flag && *s == '_')
658 { strcpy(t, "_USCORE");
659 t += 7;
660 }
661 else
662 { s = utf8(t, s);
663 t += 6;
664 }
665 if (t >= buf + sizeof(buf))
666 break;
667 }
668 *t = '\0';
669 while (knames.find(buf) != knames.end() || (reserved && reserved->find(buf) != reserved->end()))
670 { *t++ = '_';
671 *t = '\0';
672 }
673 if (isalpha(*buf) || *buf == '_' || *buf == ':')
674 { t = (char*)emalloc(strlen(buf) + 1);
675 strcpy(t, buf);
676 }
677 else
678 { t = (char*)emalloc(strlen(buf) + 2);
679 *t = '_';
680 strcpy(t + 1, buf);
681 }
682 if (lookup == LOOKUP)
683 { qnames[Pair(p,name)] = t;
684 if (vflag)
685 { cerr << "Mapping '" << p << ":" << name << "' to '" << t << "'" << endl;
686 #ifdef DEBUG
687 for (MapOfPairToString::const_iterator i = qnames.begin(); i != qnames.end(); ++i)
688 cerr << "Map[" << (*i).first.first << ":" << (*i).first.second << "]='" << (*i).second << "'" << endl;
689 #endif
690 }
691 }
692 s = t;
693 }
694 if (eqvtypemap.find(s) != eqvtypemap.end())
695 s = eqvtypemap[s];
696 return s;
697 }
698
699 bool Types::is_defined(const char *prefix, const char *URI, const char *qname)
700 { const char *t = fname(prefix, URI, qname, NULL, LOOKUP, true);
701 return usetypemap.find(t) != usetypemap.end();
702 }
703
704 const char *Types::aname(const char *prefix, const char *URI, const char *qname)
705 { return fname(prefix, URI, qname, NULL, NOLOOKUP, true);
706 }
707
708 const char *Types::cname(const char *prefix, const char *URI, const char *qname)
709 { return fname(prefix, URI, qname, NULL, LOOKUP, true);
710 }
711
712 const char *Types::tname(const char *prefix, const char *URI, const char *qname)
713 { const char *s, *t;
714 t = cname(prefix, URI, qname);
715 if (usetypemap.find(t) != usetypemap.end())
716 { s = usetypemap[t];
717 if (vflag)
718 cerr << "Mapping use of '" << t << "' to '" << s << "'" << endl;
719 }
720 else
721 { s = t;
722 fprintf(stream, "\n// Warning: undefined QName '%s' for type '%s' in namespace '%s' (FIXME: check WSDL and schema definitions)\n", qname?qname:"", t, URI?URI:"?");
723 if (vflag)
724 fprintf(stderr, "\nWarning: undefined QName '%s' for type '%s' in namespace '%s'\n", qname?qname:"", t, URI?URI:"?");
725 }
726 return s;
727 }
728
729 const char *Types::tnameptr(bool flag, const char *prefix, const char *URI, const char *qname)
730 { const char *s = pname(flag, prefix, URI, qname);
731 if (flag)
732 { if (!strncmp(s, "char*", 5))
733 return "char**";
734 if (!strchr(s, '*'))
735 { char *r = (char*)emalloc(strlen(s) + 2);
736 strcpy(r, s);
737 strcat(r, "*");
738 return r;
739 }
740 }
741 return s;
742 }
743
744 const char *Types::pname(bool flag, const char *prefix, const char *URI, const char *qname)
745 { const char *r, *s = NULL, *t;
746 t = cname(prefix, URI, qname);
747 if (flag)
748 { if (ptrtypemap.find(t) != ptrtypemap.end())
749 s = ptrtypemap[t];
750 else
751 { if (usetypemap.find(t) != usetypemap.end())
752 s = usetypemap[t];
753 if (!s)
754 { s = t;
755 fprintf(stream, "\n// Warning: undefined QName '%s' for pointer to type '%s' (FIXME: check WSDL and schema definitions)\n", qname, t);
756 if (vflag)
757 fprintf(stderr, "\nWarning: undefined QName '%s' for pointer to type '%s' in namespace '%s'\n", qname, t, URI?URI:"?");
758 }
759 r = s;
760 while (r && *r)
761 { r = strchr(r + 1, '*');
762 if (r && *(r-1) != '/' && *(r+1) != '/')
763 break;
764 }
765 if (!r) // already pointer?
766 { char *p = (char*)emalloc(strlen(s) + 2);
767 strcpy(p, s);
768 strcat(p, "*");
769 s = p;
770 }
771 if (vflag)
772 cerr << "Mapping pointer to '" << t << "' to '" << s << "'" << endl;
773 ptrtypemap[t] = s;
774 }
775 }
776 else if (usetypemap.find(t) != usetypemap.end())
777 s = usetypemap[t];
778 else
779 { s = t;
780 fprintf(stream, "\n// Warning: undefined QName '%s' for type '%s' in namespace '%s' (FIXME: check WSDL and schema definitions)\n", qname, t, URI?URI:"?");
781 if (vflag)
782 fprintf(stderr, "\nWarning: undefined QName '%s' for type '%s' in namespace '%s'\n", qname, t, URI?URI:"?");
783 }
784 return s;
785 }
786
787 const char *Types::deftname(enum Type type, const char *pointer, bool is_pointer, const char *prefix, const char *URI, const char *qname)
788 { char buf[1024];
789 char *s;
790 const char *q = NULL, *t;
791 t = fname(prefix, URI, qname, NULL, LOOKUP, true);
792 if (deftypemap[t])
793 { if (vflag)
794 fprintf(stderr, "Name %s already defined (probably in %s file)\n", qname, mapfile);
795 return NULL;
796 }
797 if (usetypemap[t])
798 { if (vflag)
799 fprintf(stderr, "Name %s is mapped\n", qname);
800 return t;
801 }
802 switch (type)
803 { case ENUM:
804 q = "enum";
805 if (yflag)
806 knames.insert(t);
807 break;
808 case STRUCT:
809 q = "struct";
810 if (yflag)
811 knames.insert(t);
812 break;
813 case CLASS:
814 case TYPEDEF:
815 knames.insert(t);
816 default:
817 break;
818 }
819 if (q)
820 { strcpy(buf, q);
821 strcat(buf, " ");
822 }
823 else
824 buf[0] = '\0';
825 strcat(buf, t);
826 if (pointer)
827 strcat(buf, pointer);
828 s = (char*)emalloc(strlen(buf) + 1);
829 strcpy(s, buf);
830 usetypemap[t] = s;
831 if (pointer || is_pointer)
832 ptrtypemap[t] = s;
833 if (vflag)
834 cerr << "Defined '" << t << "' ('" << qname << "' in namespace '" << (URI?URI:prefix?prefix:"") << "') as '" << s << endl;
835 return t;
836 }
837
838 // get enumeration value. URI/type refers to the enum simpleType.
839 const char *Types::ename(const char *type, const char *value, bool isqname)
840 { const char *s = enames[Pair(type,value)];
841 if (!s)
842 { s = fname(NULL, NULL, value, &rnames, NOLOOKUP, isqname);
843 if (!eflag && type && *type)
844 { // Add prefix to enum
845 if (!*s || (s[0] == '_' && s[1] == '\0'))
846 s = "_x0000";
847 char *buf = (char*)emalloc(strlen(type) + strlen(s) + 3);
848 // _xXXXX is OK here
849 if (s[0] == '_' && s[1] != 'x' && strncmp(s, "_USCORE", 7))
850 sprintf(buf, "%s_%s", type, s);
851 else
852 sprintf(buf, "%s__%s", type, s);
853 s = buf;
854 }
855 else
856 rnames.insert(s);
857 enames[Pair(type,value)] = s;
858 }
859 return s;
860 }
861
862 // get operation name
863 const char *Types::oname(const char *prefix, const char *URI, const char *qname)
864 { const char *s = fname(prefix, URI, qname, NULL, LOOKUP, true);
865 if (s && usetypemap.find(s) != usetypemap.end())
866 { // Avoid name clash with structs/classes of the same name
867 onames.insert(s);
868 }
869 s = fname(prefix, URI, qname, &onames, NOLOOKUP, true);
870 onames.insert(s);
871 return s;
872 }
873
874 // generate struct name
875 const char *Types::sname(const char *URI, const char *name)
876 { const char *s;
877 char *t;
878 if (!aflag && name)
879 { size_t len = 0;
880 for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i)
881 len += strlen(*i) + 1;
882 t = (char*)emalloc(len + strlen(name) + 1);
883 *t = '\0';
884 for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j)
885 { strcat(t, *j);
886 strcat(t, "-");
887 }
888 strcat(t, name);
889 s = fname("_", URI, t, &rnames, NOLOOKUP, true);
890 rnames.insert(s);
891 }
892 else if (URI)
893 { s = nsprefix(NULL, URI);
894 t = (char*)emalloc(strlen(s) + 16);
895 sprintf(t, "_%s__struct_%d", s, snum++);
896 s = t;
897 }
898 else
899 { t = (char*)emalloc(16);
900 sprintf(t, "struct_%d", snum++);
901 s = t;
902 }
903 return s;
904 }
905
906 // generate union name
907 const char *Types::uname(const char *URI)
908 { const char *s;
909 char *t;
910 if (!aflag)
911 { size_t len = 0;
912 for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i)
913 len += strlen(*i) + 1;
914 t = (char*)emalloc(len + 6);
915 strcpy(t, "union");
916 for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j)
917 { strcat(t, "-");
918 strcat(t, *j);
919 }
920 s = fname("_", URI, t, &rnames, NOLOOKUP, true);
921 rnames.insert(s);
922 }
923 else if (URI)
924 { s = nsprefix(NULL, URI);
925 t = (char*)emalloc(strlen(s) + 16);
926 sprintf(t, "_%s__union_%d", s, unum++);
927 s = t;
928 }
929 else
930 { t = (char*)emalloc(16);
931 sprintf(t, "_union_%d", unum++);
932 s = t;
933 }
934 return s;
935 }
936
937 // generate enum name
938 const char *Types::gname(const char *URI, const char *name)
939 { const char *s;
940 char *t;
941 if (!aflag && name)
942 { size_t len = 0;
943 for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i)
944 len += strlen(*i) + 1;
945 t = (char*)emalloc(len + strlen(name) + 1);
946 *t = '\0';
947 for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j)
948 { strcat(t, *j);
949 strcat(t, "-");
950 }
951 strcat(t, name);
952 s = fname("_", URI, t, &rnames, LOOKUP, true);
953 rnames.insert(s);
954 }
955 else if (URI)
956 { s = nsprefix(NULL, URI);
957 t = (char*)emalloc(strlen(s) + 16);
958 sprintf(t, "_%s__enum_%d", s, gnum++);
959 s = t;
960 }
961 else
962 { t = (char*)emalloc(16);
963 sprintf(t, "enum_%d", gnum++);
964 s = t;
965 }
966 return s;
967 }
968
969 // checks if nillable or minOccurs=0 (and no default value is present)
970 bool Types::is_nillable(const xs__element& element)
971 { return !element.default_ && (element.nillable || (element.minOccurs && !strcmp(element.minOccurs, "0")));
972 }
973
974 bool Types::is_basetypeforunion(const char *prefix, const char *URI, const char *type)
975 { const char *t = tname(prefix, URI, type);
976 if (!strcmp(t, "std::string") || !strcmp(t, "std::wstring"))
977 return false;
978 return is_basetype(prefix, URI, type);
979 }
980
981 bool Types::is_basetype(const char *prefix, const char *URI, const char *type)
982 { const char *t = tname(prefix, URI, type);
983 if (!strncmp(t, "enum ", 5))
984 return true;
985 if (strstr(t, "__") && strcmp(t, "xsd__byte"))
986 return false;
987 return !strncmp(type, "xs:", 3) || !strncmp(type, "SOAP-ENC:", 9);
988 }
989
990 void Types::dump(FILE *fd)
991 { fprintf(fd, "\nTypes:\n");
992 for (MapOfStringToString::const_iterator i = usetypemap.begin(); i != usetypemap.end(); ++i)
993 fprintf(fd, "%s=%s\n", (*i).first, (*i).second?(*i).second:"(null)");
994 fprintf(fd, "\nPointers:\n");
995 for (MapOfStringToString::const_iterator j = ptrtypemap.begin(); j != ptrtypemap.end(); ++j)
996 fprintf(fd, "%s=%s\n", (*j).first, (*j).second?(*j).second:"(null)");
997 }
998
999 void Types::define(const char *URI, const char *name, const xs__complexType& complexType)
1000 { // generate prototype for structs/classes and store name
1001 const char *prefix = NULL;
1002 if (complexType.name)
1003 name = complexType.name;
1004 else
1005 prefix = "_";
1006 if (complexType.complexContent
1007 && complexType.complexContent->restriction
1008 && !strcmp(complexType.complexContent->restriction->base, "SOAP-ENC:Array"))
1009 { if (strcmp(schema_prefix, "ns"))
1010 prefix = "*";
1011 else
1012 prefix = "";
1013 }
1014 if (cflag)
1015 { const char *t = deftname(STRUCT, "*", true, prefix, URI, name);
1016 if (t)
1017 { if (yflag)
1018 fprintf(stream, "\n/// Typedef synonym for struct %s.\ntypedef struct %s %s;\n", t, t, t);
1019 }
1020 else if (name)
1021 { t = deftypemap[cname(prefix, URI, name)];
1022 if (t)
1023 { fprintf(stream, "\n/// Imported complexType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:"");
1024 document(complexType.annotation);
1025 if (*t)
1026 format(t);
1027 else
1028 fprintf(stream, "// complexType definition intentionally left blank.\n");
1029 }
1030 }
1031 }
1032 else
1033 { const char *t = deftname(CLASS, "*", true, prefix, URI, name);
1034 if (t)
1035 fprintf(stream, "\n// Forward declaration of class %s.\nclass %s;\n", t, t);
1036 else if (name)
1037 { t = deftypemap[cname(prefix, URI, name)];
1038 if (t)
1039 { fprintf(stream, "\n/// Imported complexType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:"");
1040 document(complexType.annotation);
1041 if (*t)
1042 format(t);
1043 else
1044 fprintf(stream, "// complexType definition intentionally left blank.\n");
1045 }
1046 }
1047 }
1048 }
1049
1050 void Types::gen(const char *URI, const char *name, const xs__simpleType& simpleType, bool anonymous)
1051 { const char *t = NULL;
1052 const char *prefix = NULL;
1053 if (simpleType.name)
1054 name = simpleType.name;
1055 else
1056 prefix = "_";
1057 if (!anonymous)
1058 { t = deftypemap[cname(NULL, URI, name)];
1059 if (t)
1060 { fprintf(stream, "\n/// Imported simpleType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:"");
1061 document(simpleType.annotation);
1062 if (*t)
1063 format(t);
1064 else
1065 fprintf(stream, "// simpleType definition intentionally left blank.\n");
1066 return;
1067 }
1068 }
1069 if (simpleType.restriction)
1070 { const char *base = simpleType.restriction->base;
1071 if (!base && simpleType.restriction->simpleType)
1072 { if (!anonymous)
1073 { if (simpleType.restriction->simpleType->list && simpleType.restriction->length && simpleType.restriction->length->value)
1074 { fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction list with length %s.", URI?URI:"", name, simpleType.restriction->length->value);
1075 document(simpleType.restriction->length->annotation);
1076 }
1077 else
1078 fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction.", URI?URI:"", name);
1079 }
1080 gen(URI, name, *simpleType.restriction->simpleType, anonymous);
1081 }
1082 else
1083 { if (!base)
1084 base = "xsd:string";
1085 const char *baseURI = NULL;
1086 if (simpleType.restriction->simpleTypePtr() && simpleType.restriction->simpleTypePtr()->schemaPtr())
1087 baseURI = simpleType.restriction->simpleTypePtr()->schemaPtr()->targetNamespace;
1088 if (!anonymous)
1089 fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction of %s.\n", URI?URI:"", name, base);
1090 document(simpleType.annotation);
1091 document(simpleType.restriction->annotation);
1092 if (!simpleType.restriction->enumeration.empty())
1093 { bool is_numeric = true; // check if all enumeration values are numeric
1094 bool is_qname = !strcmp(base, "xs:QName");
1095 if (!anonymous)
1096 { t = deftname(ENUM, NULL, false, prefix, URI, name);
1097 if (t && !eflag)
1098 fprintf(stream, "/// Note: enum values are prefixed with '%s' to avoid name clashes, please use wsdl2h option -e to omit this prefix\n", t);
1099 }
1100 if (!t)
1101 t = gname(URI, name);
1102 if (!anonymous)
1103 fprintf(stream, "enum %s\n{\n", t);
1104 else
1105 fprintf(stream, " enum %s\n {\n", t);
1106 for (vector<xs__enumeration>::const_iterator enumeration1 = simpleType.restriction->enumeration.begin(); enumeration1 != simpleType.restriction->enumeration.end(); ++enumeration1)
1107 { const char *s;
1108 if ((s = (*enumeration1).value))
1109 is_numeric &= is_integer(s);
1110 }
1111 SetOfString enumvals;
1112 for (vector<xs__enumeration>::const_iterator enumeration2 = simpleType.restriction->enumeration.begin(); enumeration2 != simpleType.restriction->enumeration.end(); ++enumeration2)
1113 { const char *s;
1114 document((*enumeration2).annotation);
1115 if ((s = (*enumeration2).value))
1116 { if (!enumvals.count(s))
1117 { enumvals.insert(s);
1118 if (is_numeric)
1119 fprintf(stream, "\t%s = %s,\t///< %s value=\"%s\"\n", ename(t, s, false), s, base, s);
1120 else if (is_qname && (*enumeration2).value_)
1121 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration2).value_, true), base, (*enumeration2).value_);
1122 else
1123 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, s, false), base, s);
1124 }
1125 }
1126 else
1127 fprintf(stream, "//\tunrecognized: enumeration '%s' has no value\n", name?name:"");
1128 }
1129 if (!anonymous)
1130 { fprintf(stream, "};\n");
1131 if (yflag)
1132 fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t);
1133 if (pflag && simpleType.name)
1134 { const char *s = aname(prefix, URI, name);
1135 knames.insert(s);
1136 s = aname(prefix, URI, name);
1137 fprintf(stream, "\n/// Class wrapper\n");
1138 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
1139 fprintf(stream, elementformat, tname(prefix, URI, name), "__item;");
1140 modify(s);
1141 fprintf(stream, "\n};\n");
1142 }
1143 }
1144 else
1145 fprintf(stream, " }\n");
1146 }
1147 else
1148 { if (simpleType.restriction->length && simpleType.restriction->length->value)
1149 { fprintf(stream, "/// Length of this string is exactly %s characters\n", simpleType.restriction->length->value);
1150 document(simpleType.restriction->length->annotation);
1151 }
1152 else
1153 { const char *a = NULL, *b = NULL;
1154 if (simpleType.restriction->minLength)
1155 { a = simpleType.restriction->minLength->value;
1156 document(simpleType.restriction->minLength->annotation);
1157 }
1158 if (simpleType.restriction->maxLength)
1159 { b = simpleType.restriction->maxLength->value;
1160 document(simpleType.restriction->maxLength->annotation);
1161 }
1162 if (a || b)
1163 fprintf(stream, "/// Length of this string is within %s..%s characters\n", a?a:"0", b?b:"");
1164 }
1165 if (simpleType.restriction->precision && simpleType.restriction->precision->value)
1166 fprintf(stream, "/// %sprecision is %s (note: not automatically enforced)\n", simpleType.restriction->precision->fixed?"fixed ":"", simpleType.restriction->precision->value);
1167 if (simpleType.restriction->scale && simpleType.restriction->scale->value)
1168 fprintf(stream, "/// %sscale is %s (note: not automatically enforced)\n", simpleType.restriction->scale->fixed?"fixed ":"", simpleType.restriction->scale->value);
1169 if (simpleType.restriction->totalDigits && simpleType.restriction->totalDigits->value)
1170 fprintf(stream, "/// %snumber of total digits is %s (note: not automatically enforced)\n", simpleType.restriction->totalDigits->fixed?"fixed ":"", simpleType.restriction->totalDigits->value);
1171 if (simpleType.restriction->fractionDigits && simpleType.restriction->fractionDigits->value)
1172 fprintf(stream, "/// %snumber of fraction digits is %s (note: not automatically enforced)\n", simpleType.restriction->fractionDigits->fixed?"fixed ":"", simpleType.restriction->fractionDigits->value);
1173 for (vector<xs__pattern>::const_iterator pattern1 = simpleType.restriction->pattern.begin(); pattern1 != simpleType.restriction->pattern.end(); ++pattern1)
1174 fprintf(stream, "/// Content pattern is \"%s\" (note: not automatically enforced)\n", xstring((*pattern1).value));
1175 const char *ai = NULL, *ae = NULL, *bi = NULL, *be = NULL;
1176 if (simpleType.restriction->minInclusive)
1177 { ai = simpleType.restriction->minInclusive->value;
1178 document(simpleType.restriction->minInclusive->annotation);
1179 }
1180 else if (simpleType.restriction->minExclusive)
1181 { ae = simpleType.restriction->minExclusive->value;
1182 document(simpleType.restriction->minExclusive->annotation);
1183 }
1184 if (simpleType.restriction->maxInclusive)
1185 { bi = simpleType.restriction->maxInclusive->value;
1186 document(simpleType.restriction->maxInclusive->annotation);
1187 }
1188 else if (simpleType.restriction->maxExclusive)
1189 { be = simpleType.restriction->maxExclusive->value;
1190 document(simpleType.restriction->maxExclusive->annotation);
1191 }
1192 if (ai || ae || bi || be)
1193 { fprintf(stream, "/// Value range is ");
1194 if (ai)
1195 fprintf(stream, "[%s..", ai);
1196 else if (ae)
1197 fprintf(stream, "(%s..", ae);
1198 else
1199 fprintf(stream, "[..");
1200 if (bi)
1201 fprintf(stream, "%s]\n", bi);
1202 else if (be)
1203 fprintf(stream, "%s)\n", be);
1204 else
1205 fprintf(stream, "]\n");
1206 }
1207 if (!simpleType.restriction->attribute.empty())
1208 { if (!Wflag)
1209 fprintf(stderr, "\nWarning: simpleType '%s' should not have attributes\n", name?name:"");
1210 }
1211 const char *s = tname(NULL, baseURI, base);
1212 if (!anonymous)
1213 { bool is_ptr = false;
1214 is_ptr = (strchr(s, '*') != NULL) || (s == pname(true, NULL, baseURI, base));
1215 t = deftname(TYPEDEF, NULL, is_ptr, prefix, URI, name);
1216 if (t)
1217 fprintf(stream, "typedef %s %s", s, t);
1218 }
1219 else
1220 { t = "";
1221 fprintf(stream, elementformat, s, "");
1222 fprintf(stream, "\n");
1223 }
1224 if (t)
1225 { if (!anonymous && !simpleType.restriction->pattern.empty())
1226 { fprintf(stream, " \"");
1227 for (vector<xs__pattern>::const_iterator pattern2 = simpleType.restriction->pattern.begin(); pattern2 != simpleType.restriction->pattern.end(); ++pattern2)
1228 { if (pattern2 != simpleType.restriction->pattern.begin())
1229 fprintf(stream, "|");
1230 fprintf(stream, "%s", xstring((*pattern2).value));
1231 }
1232 fprintf(stream, "\"");
1233 }
1234 // add range info only when type is numeric
1235 bool is_numeric = false, is_float = false;
1236 if (!strncmp(s, "unsigned ", 9))
1237 s += 9;
1238 else if (!strncmp(s, "xsd__unsigned", 13))
1239 s += 13;
1240 else if (!strncmp(s, "xsd__", 5))
1241 s += 5;
1242 if (!strcmp(s, "double")
1243 || !strcmp(s, "float"))
1244 is_numeric = is_float = true;
1245 else if (!strcmp(s, "bool")
1246 || !strcmp(s, "byte")
1247 || !strcmp(s, "Byte")
1248 || !strcmp(s, "char")
1249 || !strcmp(s, "double")
1250 || !strcmp(s, "float")
1251 || !strcmp(s, "int")
1252 || !strcmp(s, "Int")
1253 || !strcmp(s, "long")
1254 || !strcmp(s, "Long")
1255 || !strcmp(s, "LONG64")
1256 || !strcmp(s, "short")
1257 || !strcmp(s, "Short")
1258 || !strcmp(s, "ULONG64"))
1259 is_numeric = true;
1260 if (!anonymous
1261 && simpleType.restriction->minLength
1262 && simpleType.restriction->minLength->value)
1263 fprintf(stream, " %s", simpleType.restriction->minLength->value);
1264 else if (is_numeric
1265 && !anonymous
1266 && simpleType.restriction->minInclusive
1267 && simpleType.restriction->minInclusive->value
1268 && is_integer(simpleType.restriction->minInclusive->value))
1269 fprintf(stream, " %s", simpleType.restriction->minInclusive->value);
1270 else if (is_float
1271 && !anonymous
1272 && simpleType.restriction->minExclusive
1273 && simpleType.restriction->minExclusive->value
1274 && is_integer(simpleType.restriction->minExclusive->value))
1275 fprintf(stream, " %s", simpleType.restriction->minExclusive->value);
1276 else if (is_numeric
1277 && !anonymous
1278 && simpleType.restriction->minExclusive
1279 && simpleType.restriction->minExclusive->value
1280 && is_integer(simpleType.restriction->minExclusive->value))
1281 fprintf(stream, " " SOAP_LONG_FORMAT, to_integer(simpleType.restriction->minExclusive->value)+1);
1282 if (!anonymous
1283 && simpleType.restriction->maxLength
1284 && simpleType.restriction->maxLength->value)
1285 fprintf(stream, ":%s", simpleType.restriction->maxLength->value);
1286 else if (is_numeric
1287 && !anonymous
1288 && simpleType.restriction->maxInclusive
1289 && simpleType.restriction->maxInclusive->value
1290 && is_integer(simpleType.restriction->maxInclusive->value))
1291 fprintf(stream, ":%s", simpleType.restriction->maxInclusive->value);
1292 else if (is_float
1293 && !anonymous
1294 && simpleType.restriction->maxExclusive
1295 && simpleType.restriction->maxExclusive->value
1296 && is_integer(simpleType.restriction->maxExclusive->value))
1297 fprintf(stream, ":%s", simpleType.restriction->maxExclusive->value);
1298 else if (is_numeric
1299 && !anonymous
1300 && simpleType.restriction->maxExclusive
1301 && simpleType.restriction->maxExclusive->value
1302 && is_integer(simpleType.restriction->maxExclusive->value))
1303 fprintf(stream, ":" SOAP_LONG_FORMAT, to_integer(simpleType.restriction->maxExclusive->value)-1);
1304 if (!anonymous)
1305 { fprintf(stream, ";\n");
1306 if (pflag && simpleType.name)
1307 { const char *s = aname(prefix, URI, name);
1308 knames.insert(s);
1309 s = aname(prefix, URI, name);
1310 fprintf(stream, "\n/// Class wrapper\n");
1311 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
1312 fprintf(stream, elementformat, tname(prefix, URI, name), "__item;");
1313 modify(s);
1314 fprintf(stream, "\n};\n");
1315 }
1316 }
1317 }
1318 }
1319 }
1320 }
1321 else if (simpleType.list)
1322 { if (simpleType.list->restriction && simpleType.list->restriction->base)
1323 { if (!anonymous)
1324 { fprintf(stream, "\n/// \"%s\":%s is a simpleType list restriction of %s.\n", URI?URI:"", name, simpleType.list->restriction->base);
1325 fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n");
1326 }
1327 document(simpleType.annotation);
1328 if (!anonymous)
1329 { t = deftname(ENUM, NULL, false, prefix, URI, name);
1330 if (t)
1331 fprintf(stream, "enum * %s\n{\n", t);
1332 }
1333 else
1334 { t = "";
1335 fprintf(stream, "enum *\n{\n");
1336 }
1337 if (t)
1338 { for (vector<xs__enumeration>::const_iterator enumeration = simpleType.list->restriction->enumeration.begin(); enumeration != simpleType.list->restriction->enumeration.end(); ++enumeration)
1339 { if ((*enumeration).value)
1340 { if (!strcmp(simpleType.list->restriction->base, "xs:QName") && (*enumeration).value_)
1341 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), simpleType.list->restriction->base, (*enumeration).value_);
1342 else
1343 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), simpleType.list->restriction->base, (*enumeration).value);
1344 }
1345 else
1346 fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t);
1347 }
1348 if (!anonymous)
1349 { fprintf(stream, "};\n");
1350 if (yflag)
1351 fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t);
1352 if (pflag && simpleType.name)
1353 { const char *s = aname(prefix, URI, name);
1354 knames.insert(s);
1355 s = aname(prefix, URI, name);
1356 fprintf(stream, "\n/// Class wrapper\n");
1357 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
1358 fprintf(stream, elementformat, tname(prefix, URI, name), "__item;");
1359 modify(s);
1360 fprintf(stream, "\n};\n");
1361 }
1362 }
1363 else
1364 fprintf(stream, "}\n");
1365 }
1366 }
1367 else if (simpleType.list->itemType)
1368 { const xs__simpleType *p = simpleType.list->itemTypePtr();
1369 if (p
1370 && p->restriction
1371 && p->restriction->base
1372 && !p->restriction->enumeration.empty()
1373 && p->restriction->enumeration.size() <= 64)
1374 { if (!anonymous)
1375 { fprintf(stream, "\n/// \"%s\":%s is a simpleType list of %s.\n", URI?URI:"", name, simpleType.list->itemType);
1376 fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n");
1377 }
1378 document(simpleType.annotation);
1379 if (!anonymous)
1380 { t = deftname(ENUM, NULL, false, prefix, URI, name);
1381 if (t)
1382 fprintf(stream, "enum * %s\n{\n", t);
1383 }
1384 else
1385 { t = "";
1386 fprintf(stream, "enum *\n{\n");
1387 }
1388 if (t)
1389 { for (vector<xs__enumeration>::const_iterator enumeration = p->restriction->enumeration.begin(); enumeration != p->restriction->enumeration.end(); ++enumeration)
1390 { if ((*enumeration).value)
1391 { if (!strcmp(p->restriction->base, "xs:QName") && (*enumeration).value_)
1392 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), p->restriction->base, (*enumeration).value_);
1393 else
1394 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), p->restriction->base, (*enumeration).value);
1395 }
1396 else
1397 fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t);
1398 }
1399 if (!anonymous)
1400 { fprintf(stream, "};\n");
1401 if (yflag)
1402 fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t);
1403 if (pflag && simpleType.name)
1404 { const char *s = aname(prefix, URI, name);
1405 knames.insert(s);
1406 s = aname(prefix, URI, name);
1407 fprintf(stream, "\n/// Class wrapper.\n");
1408 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
1409 fprintf(stream, elementformat, tname(prefix, URI, name), "__item;");
1410 modify(s);
1411 fprintf(stream, "\n};\n");
1412 }
1413 }
1414 else
1415 fprintf(stream, "}\n");
1416 }
1417 }
1418 else
1419 { const char *s;
1420 if (!strcmp(simpleType.list->itemType, "xs:QName"))
1421 s = tname(NULL, NULL, "xsd:QName");
1422 else
1423 s = tname(NULL, NULL, "xsd:string");
1424 if (!anonymous)
1425 { fprintf(stream, "\n/// \"%s\":%s is a simpleType containing a whitespace separated list of %s.\n", URI?URI:"", name, simpleType.list->itemType);
1426 t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name);
1427 }
1428 document(simpleType.annotation);
1429 if (t)
1430 fprintf(stream, "typedef %s %s;\n", s, t);
1431 else
1432 { fprintf(stream, elementformat, s, "");
1433 fprintf(stream, "\n");
1434 }
1435 }
1436 }
1437 else
1438 { if (!anonymous)
1439 { fprintf(stream, "\n/// \"%s\":%s is a simpleType list.\n", URI?URI:"", name);
1440 fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n");
1441 }
1442 document(simpleType.annotation);
1443 if (!anonymous)
1444 { t = deftname(ENUM, NULL, false, prefix, URI, name);
1445 if (t && !eflag)
1446 fprintf(stream, "/// Note: enum values are prefixed with '%s' to avoid name clashes, please use wsdl2h option -e to omit this prefix\n", t);
1447 }
1448 else
1449 t = "";
1450 if (t)
1451 { fprintf(stream, "enum * %s\n{\n", t);
1452 for (vector<xs__simpleType>::const_iterator simple = simpleType.list->simpleType.begin(); simple != simpleType.list->simpleType.end(); ++simple)
1453 { if ((*simple).restriction && (*simple).restriction->base)
1454 { for (vector<xs__enumeration>::const_iterator enumeration = (*simple).restriction->enumeration.begin(); enumeration != (*simple).restriction->enumeration.end(); ++enumeration)
1455 { if ((*enumeration).value)
1456 { if (!strcmp((*simple).restriction->base, "xs:QName") && (*enumeration).value_)
1457 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), (*simple).restriction->base, (*enumeration).value_);
1458 else
1459 fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), (*simple).restriction->base, (*enumeration).value);
1460 }
1461 else
1462 fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t);
1463 }
1464 }
1465 }
1466 if (!anonymous)
1467 { fprintf(stream, "};\n");
1468 if (yflag)
1469 fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t);
1470 if (pflag && simpleType.name)
1471 { const char *s = aname(prefix, URI, name);
1472 knames.insert(s);
1473 s = aname(prefix, URI, name);
1474 fprintf(stream, "\n/// Class wrapper.\n");
1475 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s);
1476 fprintf(stream, elementformat, tname(prefix, URI, name), "__item;");
1477 modify(s);
1478 fprintf(stream, "\n};\n");
1479 }
1480 }
1481 else
1482 fprintf(stream, "}\n");
1483 }
1484 }
1485 }
1486 else if (simpleType.union_)
1487 { if (simpleType.union_->memberTypes)
1488 { const char *s = tname(NULL, NULL, "xsd:string");
1489 if (!anonymous)
1490 t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name);
1491 fprintf(stream, "\n/// union of values \"%s\"\n", simpleType.union_->memberTypes);
1492 if (t)
1493 fprintf(stream, "typedef %s %s;\n", s, t);
1494 else
1495 { fprintf(stream, elementformat, s, "");
1496 fprintf(stream, "\n");
1497 }
1498 }
1499 else if (!simpleType.union_->simpleType.empty())
1500 { const char *s = tname(NULL, NULL, "xsd:string");
1501 fprintf(stream, "\n");
1502 if (!anonymous)
1503 t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name);
1504 for (vector<xs__simpleType>::const_iterator simpleType1 = simpleType.union_->simpleType.begin(); simpleType1 != simpleType.union_->simpleType.end(); ++simpleType1)
1505 if ((*simpleType1).restriction)
1506 { fprintf(stream, "/// union of values from \"%s\"\n", (*simpleType1).restriction->base);
1507 // TODO: are there any other types we should report here?
1508 }
1509 if (t)
1510 fprintf(stream, "typedef %s %s;\n", s, t);
1511 else
1512 { fprintf(stream, elementformat, s, "");
1513 fprintf(stream, "\n");
1514 }
1515 }
1516 else
1517 fprintf(stream, "//\tunrecognized\n");
1518 }
1519 else
1520 fprintf(stream, "//\tunrecognized simpleType\n");
1521 }
1522
1523 void Types::gen(const char *URI, const char *name, const xs__complexType& complexType, bool anonymous)
1524 { const char *t = NULL;
1525 const char *prefix = NULL;
1526 bool soapflag = false;
1527 if (complexType.name)
1528 name = complexType.name;
1529 else
1530 prefix = "_";
1531 if (anonymous && name)
1532 t = sname(URI, name);
1533 else if (name)
1534 { t = cname(prefix, URI, name);
1535 if (deftypemap[t])
1536 return;
1537 }
1538 if (name)
1539 scope.push_back(name);
1540 if (complexType.simpleContent)
1541 { if (!anonymous)
1542 fprintf(stream, "\n/// \"%s\":%s is a%s complexType with simpleContent.\n", URI?URI:"", name, complexType.abstract?"n abstract":"");
1543 document(complexType.annotation);
1544 operations(t);
1545 if (complexType.simpleContent->restriction)
1546 { if (anonymous)
1547 { if (cflag)
1548 fprintf(stream, " struct %s\n {\n", t);
1549 else
1550 fprintf(stream, " class %s\n {\n", t);
1551 }
1552 else if (cflag)
1553 fprintf(stream, "struct %s\n{\n", t);
1554 else if (pflag && complexType.name)
1555 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
1556 else
1557 fprintf(stream, "class %s\n{ public:\n", t);
1558 const char *base = "xs:string";
1559 const char *baseURI = NULL;
1560 const xs__complexType *p = &complexType;
1561 do
1562 { if (!p->simpleContent)
1563 break;
1564 if (p->simpleContent->restriction)
1565 { if (p->simpleContent->restriction->complexTypePtr())
1566 p = p->simpleContent->restriction->complexTypePtr();
1567 else
1568 { base = p->simpleContent->restriction->base;
1569 if (p->simpleContent->restriction->simpleTypePtr() && p->simpleContent->restriction->simpleTypePtr()->schemaPtr())
1570 baseURI = p->simpleContent->restriction->simpleTypePtr()->schemaPtr()->targetNamespace;
1571 break;
1572 }
1573 }
1574 else if (p->simpleContent->extension)
1575 { if (p->simpleContent->extension->complexTypePtr())
1576 p = p->simpleContent->extension->complexTypePtr();
1577 else
1578 { base = p->simpleContent->extension->base;
1579 if (p->simpleContent->extension->simpleTypePtr() && p->simpleContent->extension->simpleTypePtr()->schemaPtr())
1580 baseURI = p->simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace;
1581 break;
1582 }
1583 }
1584 else
1585 break;
1586 }
1587 while (p);
1588 fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base);
1589 fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item");
1590 fprintf(stream, ";\n");
1591 p = &complexType;
1592 bool flag = true;
1593 do
1594 { if (!p->simpleContent)
1595 break;
1596 if (p->simpleContent->restriction)
1597 { // TODO: should only generate attribute when name is different?
1598 gen(URI, p->simpleContent->restriction->attribute);
1599 if (p->simpleContent->restriction->anyAttribute && flag)
1600 { gen(URI, *p->simpleContent->restriction->anyAttribute);
1601 flag = false;
1602 }
1603 if (p->simpleContent->restriction->complexTypePtr())
1604 p = p->simpleContent->restriction->complexTypePtr();
1605 else
1606 break;
1607 }
1608 else if (p->simpleContent->extension)
1609 { gen(URI, p->simpleContent->extension->attribute);
1610 gen(URI, p->simpleContent->extension->attributeGroup);
1611 if (p->simpleContent->extension->anyAttribute && flag)
1612 { gen(URI, *p->simpleContent->extension->anyAttribute);
1613 flag = false;
1614 }
1615 if (p->simpleContent->extension->complexTypePtr())
1616 p = p->simpleContent->extension->complexTypePtr();
1617 else
1618 break;
1619 }
1620 else
1621 break;
1622 }
1623 while (p);
1624 }
1625 else if (complexType.simpleContent->extension)
1626 { const char *base = "xs:string";
1627 const char *baseURI = NULL;
1628 if (cflag || fflag || anonymous)
1629 { if (anonymous)
1630 { if (cflag)
1631 fprintf(stream, " struct %s\n {\n", t);
1632 else
1633 fprintf(stream, " class %s\n {\n", t);
1634 }
1635 else if (cflag)
1636 fprintf(stream, "struct %s\n{\n", t);
1637 else if (pflag && complexType.name)
1638 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
1639 else
1640 fprintf(stream, "class %s\n{ public:\n", t);
1641 const xs__complexType *p = &complexType;
1642 do
1643 { if (!p->simpleContent)
1644 break;
1645 if (p->simpleContent->restriction)
1646 { if (p->simpleContent->restriction->complexTypePtr())
1647 p = p->simpleContent->restriction->complexTypePtr();
1648 else
1649 { base = p->simpleContent->restriction->base;
1650 if (p->simpleContent->restriction->simpleTypePtr() && p->simpleContent->restriction->simpleTypePtr()->schemaPtr())
1651 baseURI = p->simpleContent->restriction->simpleTypePtr()->schemaPtr()->targetNamespace;
1652 break;
1653 }
1654 }
1655 else if (p->simpleContent->extension)
1656 { if (p->simpleContent->extension->complexTypePtr())
1657 p = p->simpleContent->extension->complexTypePtr();
1658 else
1659 { base = p->simpleContent->extension->base;
1660 if (p->simpleContent->extension->simpleTypePtr() && p->simpleContent->extension->simpleTypePtr()->schemaPtr())
1661 baseURI = p->simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace;
1662 break;
1663 }
1664 }
1665 else
1666 break;
1667 }
1668 while (p);
1669 fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base);
1670 fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item");
1671 fprintf(stream, ";\n");
1672 p = &complexType;
1673 bool flag = true;
1674 do
1675 { if (!p->simpleContent)
1676 break;
1677 if (p->simpleContent->restriction)
1678 { gen(URI, p->simpleContent->restriction->attribute);
1679 if (p->simpleContent->restriction->anyAttribute && flag)
1680 gen(URI, *p->simpleContent->restriction->anyAttribute);
1681 break;
1682 }
1683 else if (p->simpleContent->extension)
1684 { gen(URI, p->simpleContent->extension->attribute);
1685 gen(URI, p->simpleContent->extension->attributeGroup);
1686 if (p->simpleContent->extension->anyAttribute && flag)
1687 { gen(URI, *p->simpleContent->extension->anyAttribute);
1688 flag = false;
1689 }
1690 if (p->simpleContent->extension->complexTypePtr())
1691 p = p->simpleContent->extension->complexTypePtr();
1692 else
1693 break;
1694 }
1695 else
1696 break;
1697 }
1698 while (p);
1699 }
1700 else
1701 { base = complexType.simpleContent->extension->base;
1702 if (
1703 /* TODO: in future, may want to add check here for base type == class
1704 complexType.simpleContent->extension->simpleTypePtr()
1705 ||
1706 */
1707 complexType.simpleContent->extension->complexTypePtr())
1708 { if (complexType.simpleContent->extension->complexTypePtr()->schemaPtr())
1709 baseURI = complexType.simpleContent->extension->complexTypePtr()->schemaPtr()->targetNamespace;
1710 fprintf(stream, "class %s : public %s\n{ public:\n", t, cname(NULL, baseURI, base));
1711 soapflag = true;
1712 }
1713 else
1714 { if (complexType.simpleContent->extension->simpleTypePtr() && complexType.simpleContent->extension->simpleTypePtr()->schemaPtr())
1715 baseURI = complexType.simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace;
1716 else if (complexType.simpleContent->extension->complexTypePtr() && complexType.simpleContent->extension->complexTypePtr()->schemaPtr())
1717 baseURI = complexType.simpleContent->extension->complexTypePtr()->schemaPtr()->targetNamespace;
1718 if (pflag && complexType.name)
1719 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
1720 else
1721 fprintf(stream, "class %s\n{ public:\n", t);
1722 fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base);
1723 fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item");
1724 fprintf(stream, ";\n");
1725 }
1726 gen(URI, complexType.simpleContent->extension->attribute);
1727 gen(URI, complexType.simpleContent->extension->attributeGroup);
1728 if (complexType.simpleContent->extension->anyAttribute)
1729 gen(URI, *complexType.simpleContent->extension->anyAttribute);
1730 }
1731 }
1732 else
1733 fprintf(stream, "//\tunrecognized\n");
1734 }
1735 else if (complexType.complexContent)
1736 { if (complexType.complexContent->restriction)
1737 { if (!anonymous)
1738 fprintf(stream, "\n/// \"%s\":%s is a%s complexType with complexContent restriction of %s.\n", URI?URI:"", name, complexType.abstract?"n abstract":"", complexType.complexContent->restriction->base);
1739 document(complexType.annotation);
1740 operations(t);
1741 if (!strcmp(complexType.complexContent->restriction->base, "SOAP-ENC:Array"))
1742 { char *item = NULL, *type = NULL;
1743 if (!complexType.complexContent->restriction->attribute.empty())
1744 { xs__attribute& attribute = complexType.complexContent->restriction->attribute.front();
1745 if (attribute.wsdl__arrayType)
1746 type = attribute.wsdl__arrayType;
1747 }
1748 xs__seqchoice *s = complexType.complexContent->restriction->sequence;
1749 if (s
1750 && !s->__contents.empty()
1751 && s->__contents.front().__union == SOAP_UNION_xs__union_content_element
1752 && s->__contents.front().__content.element)
1753 { xs__element& element = *s->__contents.front().__content.element;
1754 if (!type)
1755 { if (element.type)
1756 type = element.type;
1757 else if (element.simpleTypePtr())
1758 { if (element.simpleTypePtr()->name)
1759 type = element.simpleTypePtr()->name;
1760 else if (element.simpleTypePtr()->restriction)
1761 type = element.simpleTypePtr()->restriction->base;
1762 }
1763 else if (element.complexTypePtr())
1764 { if (element.complexTypePtr()->name)
1765 type = element.complexTypePtr()->name;
1766 else if (element.complexTypePtr()->complexContent && element.complexTypePtr()->complexContent->restriction)
1767 type = element.complexTypePtr()->complexContent->restriction->base;
1768 }
1769 }
1770 item = element.name; // <sequence><element name="item" type="..."/></sequence>
1771 }
1772 gen_soap_array(name, t, item, type);
1773 }
1774 else
1775 { if (anonymous)
1776 { if (cflag)
1777 fprintf(stream, " struct %s\n {\n", t);
1778 else
1779 fprintf(stream, " class %s\n {\n", t);
1780 }
1781 else if (cflag)
1782 fprintf(stream, "struct %s\n{\n", t);
1783 else if (pflag && complexType.name)
1784 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
1785 else
1786 fprintf(stream, "class %s\n{ public:\n", t);
1787 if (complexType.complexContent->restriction->group)
1788 gen(URI, *complexType.complexContent->restriction->group, NULL, NULL);
1789 if (complexType.complexContent->restriction->all)
1790 gen(URI, *complexType.complexContent->restriction->all, NULL, NULL);
1791 if (complexType.complexContent->restriction->sequence)
1792 gen(URI, *complexType.complexContent->restriction->sequence, NULL, NULL);
1793 if (complexType.complexContent->restriction->choice)
1794 gen(URI, name, *complexType.complexContent->restriction->choice, NULL, NULL);
1795 gen(URI, complexType.complexContent->restriction->attribute);
1796 bool flag = true;
1797 if (complexType.complexContent->restriction->anyAttribute)
1798 { gen(URI, *complexType.complexContent->restriction->anyAttribute);
1799 flag = false;
1800 }
1801 const xs__complexType *p = complexType.complexContent->restriction->complexTypePtr();
1802 while (p)
1803 { const char *pURI;
1804 if (p->schemaPtr())
1805 pURI = p->schemaPtr()->targetNamespace;
1806 else
1807 pURI = URI;
1808 const char *b = cname(NULL, pURI, p->name);
1809 if (zflag && zflag <= 5)
1810 fprintf(stream, "/// RESTRICTED FROM %s:\n", b);
1811 else if (comment_nest == 0)
1812 fprintf(stream, "/* RESTRICTED FROM %s:\n", b);
1813 else
1814 fprintf(stream, " RESTRICTED FROM %s:\n", b);
1815 comment_nest++;
1816 if (p->complexContent && p->complexContent->restriction)
1817 { gen(URI, p->complexContent->restriction->attribute);
1818 if (p->complexContent->restriction->anyAttribute && flag)
1819 { gen(URI, *p->complexContent->restriction->anyAttribute);
1820 flag = false;
1821 }
1822 p = p->complexContent->restriction->complexTypePtr();
1823 }
1824 else if (p->complexContent && p->complexContent->extension)
1825 { gen(URI, p->complexContent->extension->attribute);
1826 gen(URI, p->complexContent->extension->attributeGroup);
1827 if (p->complexContent->extension->anyAttribute && flag)
1828 { gen(URI, *p->complexContent->extension->anyAttribute);
1829 flag = false;
1830 }
1831 p = p->complexContent->extension->complexTypePtr();
1832 }
1833 else
1834 { gen(URI, p->attribute);
1835 gen(URI, p->attributeGroup);
1836 if (p->anyAttribute && flag)
1837 gen(URI, *p->anyAttribute);
1838 p = NULL;
1839 }
1840 comment_nest--;
1841 if (zflag && zflag <= 5)
1842 fprintf(stream, "// END OF RESTRICTED FROM %s\n", b);
1843 else if (comment_nest == 0)
1844 fprintf(stream, " END OF RESTRICTED FROM %s */\n", b);
1845 else
1846 fprintf(stream, " END OF RESTRICTED FROM %s\n", b);
1847 }
1848 }
1849 }
1850 else if (complexType.complexContent->extension)
1851 { const char *base = complexType.complexContent->extension->base;
1852 xs__complexType *p = complexType.complexContent->extension->complexTypePtr();
1853 if (!anonymous)
1854 fprintf(stream, "\n/// \"%s\":%s is a%s complexType with complexContent extension of %s.\n", URI?URI:"", name, complexType.abstract?"n abstract":"", base);
1855 document(complexType.annotation);
1856 operations(t);
1857 if (anonymous)
1858 { if (cflag)
1859 fprintf(stream, " struct %s\n {\n", t);
1860 else
1861 fprintf(stream, " class %s\n {\n", t);
1862 }
1863 else if (cflag)
1864 fprintf(stream, "struct %s\n{\n", t);
1865 else if (fflag)
1866 fprintf(stream, "class %s\n{ public:\n", t);
1867 else // TODO: what to do if base class is in another namespace and elements must be qualified in XML payload?
1868 { const char *baseURI = NULL;
1869 if (p && p->schemaPtr())
1870 baseURI = p->schemaPtr()->targetNamespace;
1871 fprintf(stream, "class %s : public %s\n{ public:\n", t, cname(NULL, baseURI, base));
1872 soapflag = true;
1873 }
1874 gen_inh(URI, p, anonymous);
1875 if (complexType.complexContent->extension->group)
1876 gen(URI, *complexType.complexContent->extension->group, NULL, NULL);
1877 if (complexType.complexContent->extension->all)
1878 gen(URI, *complexType.complexContent->extension->all, NULL, NULL);
1879 if (complexType.complexContent->extension->sequence)
1880 gen(URI, *complexType.complexContent->extension->sequence, NULL, NULL);
1881 if (complexType.complexContent->extension->choice)
1882 gen(URI, name, *complexType.complexContent->extension->choice, NULL, NULL);
1883 gen(URI, complexType.complexContent->extension->attribute);
1884 gen(URI, complexType.complexContent->extension->attributeGroup);
1885 if (complexType.complexContent->extension->anyAttribute)
1886 gen(URI, *complexType.complexContent->extension->anyAttribute);
1887 }
1888 else
1889 fprintf(stream, "//\tunrecognized\n");
1890 }
1891 else
1892 { if (!anonymous)
1893 fprintf(stream, "\n/// \"%s\":%s is a%s complexType.\n", URI?URI:"", name, complexType.abstract?"n abstract":"");
1894 document(complexType.annotation);
1895 operations(t);
1896 if (anonymous)
1897 { if (cflag)
1898 fprintf(stream, " struct %s\n {\n", t);
1899 else
1900 fprintf(stream, " class %s\n {\n", t);
1901 }
1902 else if (cflag)
1903 fprintf(stream, "struct %s\n{\n", t);
1904 else if (pflag && complexType.name)
1905 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
1906 else
1907 fprintf(stream, "class %s\n{ public:\n", t);
1908 if (complexType.all)
1909 gen(URI, *complexType.all, NULL, NULL);
1910 else if (complexType.choice)
1911 gen(URI, name, *complexType.choice, NULL, NULL);
1912 else if (complexType.sequence)
1913 gen(URI, *complexType.sequence, NULL, NULL);
1914 else if (complexType.any)
1915 gen(URI, *complexType.any, NULL, NULL);
1916 }
1917 gen(URI, complexType.attribute);
1918 gen(URI, complexType.attributeGroup);
1919 if (complexType.anyAttribute)
1920 gen(URI, *complexType.anyAttribute);
1921 if (complexType.mixed
1922 || ( complexType.complexContent
1923 && complexType.complexContent->extension
1924 && complexType.complexContent->extension->complexTypePtr()
1925 && complexType.complexContent->extension->complexTypePtr()->mixed
1926 ))
1927 { fprintf(stream, "/// TODO: this mixed complexType is user-definable.\n/// Consult the protocol documentation to change or insert declarations.\n/// Use wsdl2h option -d for xsd__anyType DOM (soap_dom_element).\n");
1928 if (dflag)
1929 { if (with_union)
1930 fprintf(stream, pointerformat, "xsd__anyType", "__mixed");
1931 else
1932 fprintf(stream, elementformat, "xsd__anyType", "__mixed");
1933 fprintf(stream, "0;\t///< Catch mixed content in DOM soap_dom_element linked node structure.\n");
1934 }
1935 else
1936 { fprintf(stream, elementformat, "_XML", "__mixed");
1937 fprintf(stream, "0;\t///< Catch mixed content in XML string\n");
1938 }
1939 }
1940 if (t)
1941 modify(t);
1942 if (!anonymous)
1943 { if (!cflag
1944 && !(pflag && complexType.name)
1945 && !soapflag)
1946 { if (!complexType.complexContent || !complexType.complexContent->extension || !complexType.complexContent->extension->complexTypePtr())
1947 { fprintf(stream, "/// A handle to the soap struct that manages this instance (automatically set)\n");
1948 fprintf(stream, pointerformat, "struct soap", "soap");
1949 fprintf(stream, ";\n");
1950 }
1951 }
1952 fprintf(stream, "};\n");
1953 }
1954 scope.pop_back();
1955 }
1956
1957 void Types::gen(const char *URI, const vector<xs__attribute>& attributes)
1958 { for (vector<xs__attribute>::const_iterator attribute = attributes.begin(); attribute != attributes.end(); ++attribute)
1959 gen(URI, *attribute);
1960 }
1961
1962 void Types::gen(const char *URI, const xs__attribute& attribute)
1963 { const char *name, *type, *nameURI = NULL, *typeURI = NULL, *nameprefix = NULL, *typeprefix = NULL;
1964 name = attribute.name;
1965 type = attribute.type;
1966 bool is_optional = attribute.use != required && attribute.use != default_ && attribute.use != fixed_ && !attribute.default_;
1967 document(attribute.annotation);
1968 if (!URI)
1969 URI = attribute.schemaPtr()->targetNamespace;
1970 if (attribute.form)
1971 { if (*attribute.form == qualified)
1972 nameURI = URI;
1973 else
1974 nameprefix = ":";
1975 }
1976 if (URI && attribute.schemaPtr() && attribute.schemaPtr()->targetNamespace && strcmp(URI, attribute.schemaPtr()->targetNamespace))
1977 nameURI = attribute.schemaPtr()->targetNamespace; // handles attributeGroup defined in another namespace
1978 if (attribute.attributePtr()) // attribute ref
1979 { name = attribute.attributePtr()->name;
1980 type = attribute.attributePtr()->type;
1981 if (!type)
1982 { type = name;
1983 typeprefix = "_";
1984 }
1985 if (attribute.attributePtr()->schemaPtr())
1986 { typeURI = attribute.attributePtr()->schemaPtr()->targetNamespace;
1987 if (attribute.form && *attribute.form == unqualified)
1988 nameprefix = ":";
1989 else if (zflag != 3 && zflag != 2
1990 && URI
1991 && typeURI
1992 && attribute.schemaPtr()->elementFormDefault == qualified
1993 && !strcmp(URI, typeURI))
1994 nameprefix = NULL;
1995 else if (zflag == 3
1996 && URI
1997 && typeURI
1998 && attribute.schemaPtr()->attributeFormDefault == unqualified
1999 && !strcmp(URI, typeURI))
2000 nameprefix = NULL;
2001 else
2002 nameURI = typeURI;
2003 }
2004 fprintf(stream, "/// Attribute reference %s.\n", attribute.ref);
2005 document(attribute.attributePtr()->annotation);
2006 fprintf(stream, attributeformat, pname(is_optional, typeprefix, typeURI, type), aname(nameprefix, nameURI, name)); // make sure no name - type clash
2007 }
2008 else if (name && type)
2009 { fprintf(stream, "/// Attribute %s of type %s.\n", name, type);
2010 fprintf(stream, attributeformat, pname(is_optional, NULL, URI, type), aname(nameprefix, nameURI, name)); // make sure no name - type clash
2011 }
2012 else if (name && attribute.simpleTypePtr())
2013 { fprintf(stream, "@");
2014 gen(URI, name, *attribute.simpleTypePtr(), true);
2015 // 8/1/09 Changed (is_optional && !cflag && !sflag) to is_optional
2016 fprintf(stream, is_optional ? pointerformat : elementformat, "", aname(nameprefix, nameURI, name));
2017 }
2018 else if (attribute.ref)
2019 { fprintf(stream, "/// Imported attribute reference %s.\n", attribute.ref);
2020 fprintf(stream, attributeformat, pname(is_optional, "_", NULL, attribute.ref), aname(NULL, NULL, attribute.ref));
2021 }
2022 else
2023 { fprintf(stream, "/// Attribute '%s' has no type or ref: assuming string content.\n", name?name:"");
2024 fprintf(stream, attributeformat, tname(NULL, NULL, "xs:string"), aname(NULL, nameURI, name));
2025 }
2026 switch (attribute.use)
2027 { case prohibited:
2028 fprintf(stream, " 0:0");
2029 break;
2030 case required:
2031 fprintf(stream, " 1");
2032 break;
2033 default:
2034 fprintf(stream, " 0");
2035 break;
2036 }
2037 if (attribute.default_
2038 || (attribute.fixed && !is_optional))
2039 { const char *value, *QName;
2040 if (attribute.default_)
2041 { value = attribute.default_;
2042 QName = attribute.default__;
2043 }
2044 else
2045 { value = attribute.fixed;
2046 QName = attribute.fixed_;
2047 }
2048 const char *t = NULL;
2049 if (!type && attribute.simpleTypePtr())
2050 { if (attribute.simpleTypePtr()->restriction && attribute.simpleTypePtr()->restriction->base)
2051 { if (!attribute.simpleTypePtr()->restriction->enumeration.empty())
2052 { const char *s;
2053 if (is_integer(value))
2054 fprintf(stream, " = %s", value);
2055 else if (!*value)
2056 fprintf(stream, " = 0");
2057 else if ((s = enames[Pair(gname(URI, name),value)]))
2058 fprintf(stream, " = %s", s);
2059 }
2060 else
2061 { const char *baseURI = NULL;
2062 if (attribute.simpleTypePtr()->restriction->simpleTypePtr() && attribute.simpleTypePtr()->restriction->simpleTypePtr()->schemaPtr())
2063 baseURI = attribute.simpleTypePtr()->restriction->simpleTypePtr()->schemaPtr()->targetNamespace;
2064 t = tname(NULL, baseURI, attribute.simpleTypePtr()->restriction->base);
2065 }
2066 }
2067 }
2068 if (type && !t)
2069 t = tname(NULL, typeURI?typeURI:URI, type);
2070 if (t)
2071 { if (!strncmp(t, "unsigned ", 9))
2072 t += 9;
2073 else if (!strncmp(t, "xsd__unsigned", 13))
2074 t += 13;
2075 else if (!strncmp(t, "xsd__", 5))
2076 t += 5;
2077 if (!strcmp(t, "bool")
2078 || !strcmp(t, "byte")
2079 || !strcmp(t, "Byte")
2080 || !strcmp(t, "char")
2081 || !strcmp(t, "double")
2082 || !strcmp(t, "float")
2083 || !strcmp(t, "int")
2084 || !strcmp(t, "Int")
2085 || !strcmp(t, "long")
2086 || !strcmp(t, "Long")
2087 || !strcmp(t, "LONG64")
2088 || !strcmp(t, "short")
2089 || !strcmp(t, "Short")
2090 || !strcmp(t, "ULONG64"))
2091 fprintf(stream, " = %s", value);
2092 else if (!strncmp(t, "enum ", 5))
2093 { const char *s;
2094 if (is_integer(value))
2095 fprintf(stream, " = %s", value);
2096 else if (!*value)
2097 fprintf(stream, " = 0");
2098 else if ((s = enames[Pair(t + 5,value)]))
2099 fprintf(stream, " = %s", s);
2100 }
2101 else if (!strcmp(t, "char*")
2102 || !strcmp(t, "char *") // not elegant
2103 || !strcmp(t, "std::string")
2104 || !strcmp(t, "std::string*")
2105 || !strcmp(t, "std::string *")) // not elegant
2106 fprintf(stream, " = \"%s\"", cstring(value));
2107 else if (!strcmp(t, "xsd__QName") && QName) // QName
2108 fprintf(stream, " = \"%s\"", cstring(QName));
2109 }
2110 if (attribute.default_)
2111 fprintf(stream, ";\t///< Default value=\"%s\".\n", value);
2112 else
2113 fprintf(stream, ";\t///< Fixed required value=\"%s\".\n", value);
2114 }
2115 else if (attribute.fixed)
2116 fprintf(stream, ";\t///< Fixed optional value=\"%s\".\n", attribute.fixed);
2117 else if (attribute.use == required)
2118 fprintf(stream, ";\t///< Required attribute.\n");
2119 else if (attribute.use == prohibited)
2120 fprintf(stream, ";\t///< Prohibited attribute.\n");
2121 else
2122 fprintf(stream, ";\t///< Optional attribute.\n");
2123 }
2124
2125 void Types::gen(const char *URI, const vector<xs__attributeGroup>& attributeGroups)
2126 { for (vector<xs__attributeGroup>::const_iterator attributeGroup = attributeGroups.begin(); attributeGroup != attributeGroups.end(); ++attributeGroup)
2127 { const xs__attributeGroup *ag = &*attributeGroup;
2128 if (ag->attributeGroupPtr()) // attributeGroup ref
2129 ag = ag->attributeGroupPtr();
2130 fprintf(stream, "/// Begin attributeGroup %s.\n", ag->name?ag->name:ag->ref?ag->ref:"");
2131 gen(URI, ag->attribute);
2132 gen(URI, ag->attributeGroup);
2133 if (ag->anyAttribute)
2134 gen(URI, *ag->anyAttribute);
2135 fprintf(stream, "/// End of attributeGroup %s.\n", ag->name?ag->name:ag->ref?ag->ref:"");
2136 }
2137 }
2138
2139 void Types::gen(const char *URI, const vector<xs__all>& alls)
2140 { for (vector<xs__all>::const_iterator all = alls.begin(); all != alls.end(); ++all)
2141 gen(URI, *all, NULL, NULL);
2142 }
2143
2144 void Types::gen(const char *URI, const xs__all& all, const char *minOccurs, const char *maxOccurs)
2145 { bool tmp_union1 = with_union;
2146 bool tmp_union2 = fake_union;
2147 with_union = false;
2148 fake_union = false;
2149 gen(URI, all.element, minOccurs, maxOccurs);
2150 with_union = tmp_union1;
2151 fake_union = tmp_union2;
2152 }
2153
2154 void Types::gen(const char *URI, const vector<xs__contents>& contents)
2155 { for (vector<xs__contents>::const_iterator content = contents.begin(); content != contents.end(); ++content)
2156 { switch ((*content).__union)
2157 { case SOAP_UNION_xs__union_content_element:
2158 if ((*content).__content.element)
2159 gen(URI, *(*content).__content.element, true, NULL, NULL);
2160 break;
2161 case SOAP_UNION_xs__union_content_group:
2162 if ((*content).__content.group)
2163 gen(URI, *(*content).__content.group, NULL, NULL);
2164 break;
2165 case SOAP_UNION_xs__union_content_choice:
2166 if ((*content).__content.choice)
2167 gen(URI, NULL, *(*content).__content.choice, NULL, NULL);
2168 break;
2169 case SOAP_UNION_xs__union_content_sequence:
2170 if ((*content).__content.sequence)
2171 gen(URI, *(*content).__content.sequence, NULL, NULL);
2172 break;
2173 case SOAP_UNION_xs__union_content_any:
2174 if ((*content).__content.any)
2175 gen(URI, *(*content).__content.any, NULL, NULL);
2176 break;
2177 }
2178 }
2179 }
2180
2181 void Types::gen(const char *URI, const xs__seqchoice& sequence, const char *minOccurs, const char *maxOccurs)
2182 { const char *s = NULL;
2183 char *t = NULL;
2184 bool tmp_union = with_union;
2185 with_union = false;
2186 if (sequence.minOccurs)
2187 minOccurs = sequence.minOccurs;
2188 if (sequence.maxOccurs)
2189 maxOccurs = sequence.maxOccurs;
2190 if ((minOccurs && strcmp(minOccurs, "1"))
2191 || (maxOccurs && strcmp(maxOccurs, "1")))
2192 { fprintf(stream, "/// SEQUENCE <xs:sequence");
2193 if (minOccurs)
2194 fprintf(stream, " minOccurs=\"%s\"", minOccurs);
2195 if (maxOccurs)
2196 fprintf(stream, " maxOccurs=\"%s\"", maxOccurs);
2197 fprintf(stream, ">\n");
2198 document(sequence.annotation);
2199 s = sname(URI, "sequence");
2200 t = (char*)emalloc(strlen(s)+2);
2201 strcpy(t, "_");
2202 strcat(t, s);
2203 s = strstr(s, "__");
2204 if (!s)
2205 s = t;
2206 if (cflag || sflag || zflag == 2)
2207 { fprintf(stream, sizeformat, "int", s + 1);
2208 if (!fake_union && minOccurs)
2209 fprintf(stream, " %s", minOccurs);
2210 if (maxOccurs
2211 && strcmp(maxOccurs, "1")
2212 && is_integer(maxOccurs))
2213 fprintf(stream, ":%s", maxOccurs);
2214 fprintf(stream, ";\n");
2215 }
2216 else
2217 { fprintf(stream, elementformat, "std::vector<", "");
2218 fprintf(stream, "\n");
2219 }
2220 if (cflag)
2221 fprintf(stream, " struct %s\n {\n", t);
2222 else
2223 fprintf(stream, " class %s\n {\n", t);
2224 }
2225 else
2226 { if (fake_union)
2227 fprintf(stream, "/// SEQUENCE <xs:sequence>\n");
2228 document(sequence.annotation);
2229 }
2230 gen(URI, sequence.__contents);
2231 if (s)
2232 { if (cflag || sflag || zflag == 2)
2233 fprintf(stream, pointerformat, "}", s);
2234 else
2235 { fprintf(stream, elementformat, "}>", s);
2236 if (!fake_union && minOccurs)
2237 fprintf(stream, " %s", minOccurs);
2238 if (maxOccurs
2239 && strcmp(maxOccurs, "1")
2240 && is_integer(maxOccurs))
2241 fprintf(stream, ":%s", maxOccurs);
2242 }
2243 fprintf(stream, ";\n");
2244 }
2245 if (s || fake_union)
2246 fprintf(stream, "// END OF SEQUENCE\n");
2247 with_union = tmp_union;
2248 }
2249
2250 void Types::gen(const char *URI, const vector<xs__element>& elements, const char *minOccurs, const char *maxOccurs)
2251 { for (vector<xs__element>::const_iterator element = elements.begin(); element != elements.end(); ++element)
2252 gen(URI, *element, true, minOccurs, maxOccurs);
2253 }
2254
2255 void Types::gen(const char *URI, const xs__element& element, bool substok, const char *minOccurs, const char *maxOccurs)
2256 { const char *name, *type, *nameURI = NULL, *typeURI = NULL, *nameprefix = NULL, *typeprefix = NULL;
2257 name = element.name;
2258 type = element.type;
2259 document(element.annotation);
2260 if (!URI)
2261 URI = element.schemaPtr()->targetNamespace;
2262 if (element.minOccurs)
2263 minOccurs = element.minOccurs;
2264 if (element.maxOccurs)
2265 maxOccurs = element.maxOccurs;
2266 if (element.xmime__expectedContentTypes)
2267 fprintf(stream, "/// MTOM attachment with content types %s.\n", element.xmime__expectedContentTypes);
2268 if (element.form)
2269 { if (*element.form == qualified)
2270 nameURI = URI;
2271 else
2272 nameprefix = ":";
2273 }
2274 if (element.elementPtr()) // element ref
2275 { name = element.elementPtr()->name;
2276 type = element.elementPtr()->type;
2277 if (!type)
2278 { type = name;
2279 typeprefix = "_";
2280 }
2281 if (element.elementPtr()->schemaPtr())
2282 { typeURI = element.elementPtr()->schemaPtr()->targetNamespace;
2283 if (element.form && *element.form == unqualified)
2284 nameprefix = ":";
2285 else if (zflag != 3 && zflag != 2
2286 && URI
2287 && typeURI
2288 && element.schemaPtr()->elementFormDefault == qualified
2289 && !strcmp(URI, typeURI))
2290 nameprefix = NULL;
2291 else if (zflag == 3
2292 && URI
2293 && typeURI
2294 && element.schemaPtr()->elementFormDefault == unqualified
2295 && !strcmp(URI, typeURI))
2296 nameprefix = NULL;
2297 else
2298 nameURI = typeURI;
2299 }
2300 document(element.elementPtr()->annotation);
2301 if (element.elementPtr()->xmime__expectedContentTypes)
2302 fprintf(stream, "/// MTOM attachment with content types %s.\n", element.elementPtr()->xmime__expectedContentTypes);
2303 if (substok && element.elementPtr()->abstract)
2304 { fprintf(stream, "/// Reference %s to abstract element.\n", element.ref);
2305 gen_substitutions(URI, element);
2306 }
2307 else if (substok
2308 && element.elementPtr()->substitutionsPtr()
2309 && !element.elementPtr()->substitutionsPtr()->empty())
2310 { if (vflag)
2311 fprintf(stderr, "\nWarning: element ref '%s' stands as the head of a substitutionGroup but is not declared abstract\n", element.ref);
2312 gen_substitutions(URI, element);
2313 }
2314 else if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2315 { const char *s = tnameptr(cflag && zflag != 1, typeprefix, typeURI, type);
2316 if (cflag || sflag)
2317 { fprintf(stream, "/// Size of the dynamic array of %s is %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2318 fprintf(stream, sizeformat, "int", aname(NULL, NULL, name));
2319 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2320 if (is_integer(maxOccurs))
2321 fprintf(stream, ":%s", maxOccurs);
2322 fprintf(stream, ";\n");
2323 if (cflag && zflag != 1)
2324 { fprintf(stream, "/// Array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2325 fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name));
2326 }
2327 else
2328 { fprintf(stream, "/// Pointer to array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2329 fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name));
2330 }
2331 }
2332 else
2333 { fprintf(stream, "/// Vector of %s element refs with length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2334 if (with_union)
2335 fprintf(stream, pointervectorformat, s, aname(nameprefix, nameURI, name));
2336 else
2337 fprintf(stream, vectorformat, s, aname(nameprefix, nameURI, name));
2338 }
2339 }
2340 else
2341 { fprintf(stream, "/// Element reference %s.\n", element.ref);
2342 fprintf(stream, elementformat, pname((with_union && !cflag && !is_basetypeforunion(typeprefix, typeURI, type)) || fake_union || is_nillable(element), typeprefix, typeURI, type), aname(nameprefix, nameURI, name));
2343 }
2344 }
2345 else if (name && type)
2346 { if (substok && element.abstract)
2347 { fprintf(stream, "/// Abstract element %s of type %s.\n", name, type);
2348 gen_substitutions(URI, element);
2349 }
2350 else if (substok
2351 && element.substitutionsPtr()
2352 && !element.substitutionsPtr()->empty())
2353 { if (vflag)
2354 fprintf(stderr, "\nWarning: element '%s' stands as the head of a substitutionGroup but is not declared abstract\n", name);
2355 gen_substitutions(URI, element);
2356 }
2357 else if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2358 { const char *s = tnameptr(cflag && zflag != 1, NULL, URI, type);
2359 if (cflag || sflag)
2360 { fprintf(stream, "/// Size of array of %s is %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2361 fprintf(stream, sizeformat, "int", aname(NULL, NULL, name));
2362 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2363 if (is_integer(maxOccurs))
2364 fprintf(stream, ":%s", maxOccurs);
2365 fprintf(stream, ";\n");
2366 if (cflag && zflag != 1)
2367 { fprintf(stream, "/// Array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2368 fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name));
2369 }
2370 else
2371 { fprintf(stream, "/// Pointer to array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2372 fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name));
2373 }
2374 }
2375 else
2376 { fprintf(stream, "/// Vector of %s with length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs);
2377 if (with_union)
2378 fprintf(stream, pointervectorformat, s, aname(nameprefix, nameURI, name));
2379 else
2380 fprintf(stream, vectorformat, s, aname(nameprefix, nameURI, name));
2381 }
2382 }
2383 else
2384 { fprintf(stream, "/// Element %s of type %s.\n", name, type);
2385 fprintf(stream, elementformat, pname((with_union && !cflag && !is_basetypeforunion(NULL, URI, type)) || (fake_union && !element.default_) || is_nillable(element), NULL, URI, type), aname(nameprefix, nameURI, name));
2386 }
2387 }
2388 else if (name && element.simpleTypePtr())
2389 { const char *s = "";
2390 document(element.simpleTypePtr()->annotation);
2391 if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2392 { if (cflag || sflag)
2393 { fprintf(stream, "/// Size of %s array is %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs);
2394 fprintf(stream, sizeformat, "int", aname(NULL, NULL, name));
2395 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2396 if (is_integer(maxOccurs))
2397 fprintf(stream, ":%s", maxOccurs);
2398 fprintf(stream, ";\n");
2399 }
2400 else
2401 { s = ">";
2402 fprintf(stream, "/// Vector of %s with length %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs);
2403 fprintf(stream, vectorformat_open, "\n");
2404 }
2405 }
2406 gen(URI, name, *element.simpleTypePtr(), true);
2407 if (is_nillable(element)
2408 || ((cflag || sflag ) && maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2409 || (with_union && !cflag)
2410 || (fake_union && !element.default_))
2411 fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name));
2412 else
2413 fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name));
2414 }
2415 else if (name && element.complexTypePtr())
2416 { const char *s = "}";
2417 document(element.complexTypePtr()->annotation);
2418 if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2419 { if (cflag || sflag)
2420 { fprintf(stream, "/// Size of %s array is %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs);
2421 fprintf(stream, sizeformat, "int", aname(NULL, NULL, name));
2422 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2423 if (is_integer(maxOccurs))
2424 fprintf(stream, ":%s", maxOccurs);
2425 fprintf(stream, ";\n");
2426 }
2427 else
2428 { s = "}>";
2429 fprintf(stream, "/// Vector of %s with length %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs);
2430 fprintf(stream, vectorformat_open, "\n");
2431 }
2432 }
2433 gen(URI, name, *element.complexTypePtr(), true);
2434 if (is_nillable(element)
2435 || ((cflag || sflag ) && maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2436 || (with_union && !cflag)
2437 || (fake_union && !element.default_))
2438 fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name));
2439 else
2440 fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name));
2441 }
2442 else if (element.ref)
2443 { fprintf(stream, "/// Imported element reference %s.\n", element.ref);
2444 if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2445 { if (cflag || sflag)
2446 { fprintf(stream, "/// Size of %s array is %s..%s\n", element.ref, minOccurs ? minOccurs : "1", maxOccurs);
2447 fprintf(stream, sizeformat, "int", aname(NULL, NULL, element.ref));
2448 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2449 if (is_integer(maxOccurs))
2450 fprintf(stream, ":%s", maxOccurs);
2451 fprintf(stream, ";\n");
2452 fprintf(stream, pointerformat, pname(true, "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref));
2453 }
2454 else
2455 { fprintf(stream, "/// Vector of %s with length %s..%s\n", element.ref, minOccurs ? minOccurs : "1", maxOccurs);
2456 fprintf(stream, vectorformat, pname(false, "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref));
2457 }
2458 }
2459 else
2460 fprintf(stream, elementformat, pname((with_union && !cflag) || fake_union || is_nillable(element), "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref));
2461 }
2462 else if (name)
2463 { fprintf(stream, "/// Element '%s' has no type or ref (empty or with XML content).\n", name?name:"");
2464 if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1"
2465 { if (cflag || sflag)
2466 { fprintf(stream, sizeformat, "int", aname(NULL, NULL, name));
2467 fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1");
2468 if (is_integer(maxOccurs))
2469 fprintf(stream, ":%s", maxOccurs);
2470 fprintf(stream, ";\n");
2471 fprintf(stream, "/// Pointer to array of XML.\n");
2472 fprintf(stream, pointerformat, "_XML", aname(NULL, nameURI, name));
2473 }
2474 else
2475 { fprintf(stream, "/// Vector of XML with length %s..%s\n", minOccurs ? minOccurs : "1", maxOccurs);
2476 if (with_union)
2477 fprintf(stream, pointervectorformat, "_XML", aname(NULL, nameURI, name));
2478 else
2479 fprintf(stream, vectorformat, "_XML", aname(NULL, nameURI, name));
2480 }
2481 }
2482 else
2483 fprintf(stream, elementformat, "_XML", aname(NULL, nameURI, name));
2484 }
2485 else
2486 fprintf(stream, "/// Element has no name, type, or ref.");
2487 if (!substok
2488 || ( !(element.elementPtr() && element.elementPtr()->abstract)
2489 && !(element.substitutionsPtr() && !element.substitutionsPtr()->empty())
2490 && !(element.elementPtr() && element.elementPtr()->substitutionsPtr() && !element.elementPtr()->substitutionsPtr()->empty())
2491 ))
2492 { if (!fake_union && !minOccurs && !element.nillable && !element.default_ && !element.abstract)
2493 fprintf(stream, " 1");
2494 else if (!fake_union && minOccurs)
2495 fprintf(stream, " %s", minOccurs);
2496 if (maxOccurs && strcmp(maxOccurs, "1") && is_integer(maxOccurs))
2497 fprintf(stream, ":%s", maxOccurs);
2498 if (element.default_
2499 || ( element.fixed
2500 && !fake_union
2501 && (!minOccurs || !strcmp(minOccurs, "1"))
2502 && (!maxOccurs || !strcmp(maxOccurs, "1"))
2503 ))
2504 { // determine whether the element can be assigned a default value, this is dependent on the choice of mapping for primitive types
2505 const char *value, *QName;
2506 if (element.default_)
2507 { value = element.default_;
2508 QName = element.default__;
2509 }
2510 else
2511 { value = element.fixed;
2512 QName = element.fixed_;
2513 }
2514 if (type)
2515 { const char *t = tname(NULL, typeURI?typeURI:URI, type);
2516 if (!strncmp(t, "unsigned ", 9))
2517 t += 9;
2518 else if (!strncmp(t, "xsd__unsigned", 13))
2519 t += 13;
2520 else if (!strncmp(t, "xsd__", 5))
2521 t += 5;
2522 if (!strcmp(t, "bool")
2523 || !strcmp(t, "byte")
2524 || !strcmp(t, "Byte")
2525 || !strcmp(t, "char")
2526 || !strcmp(t, "double")
2527 || !strcmp(t, "float")
2528 || !strcmp(t, "int")
2529 || !strcmp(t, "Int")
2530 || !strcmp(t, "long")
2531 || !strcmp(t, "Long")
2532 || !strcmp(t, "LONG64")
2533 || !strcmp(t, "short")
2534 || !strcmp(t, "Short")
2535 || !strcmp(t, "ULONG64"))
2536 fprintf(stream, " = %s", value);
2537 else if (!strncmp(t, "enum ", 5))
2538 { const char *s;
2539 if (is_integer(value))
2540 fprintf(stream, " = %s", value);
2541 else if (!*value)
2542 fprintf(stream, " = 0");
2543 else if ((s = enames[Pair(t + 5, value)]))
2544 fprintf(stream, " = %s", s);
2545 }
2546 else if (!strcmp(t, "char*")
2547 || !strcmp(t, "char *") // not elegant
2548 || !strcmp(t, "std::string")
2549 || !strcmp(t, "std::string*")
2550 || !strcmp(t, "std::string *")) // not elegant
2551 fprintf(stream, " = \"%s\"", cstring(value));
2552 else if (!strcmp(t, "xsd__QName") && QName) // QName
2553 fprintf(stream, " = \"%s\"", cstring(QName));
2554 }
2555 if (element.default_)
2556 fprintf(stream, ";\t///< Default value=\"%s\".\n", value);
2557 else
2558 fprintf(stream, ";\t///< Fixed required value=\"%s\".\n", value);
2559 }
2560 else if (element.nillable)
2561 fprintf(stream, ";\t///< Nillable pointer.\n");
2562 else if (!fake_union && (!minOccurs || !strcmp(minOccurs, "1")) && (!maxOccurs || !strcmp(maxOccurs, "1")))
2563 fprintf(stream, ";\t///< Required element.\n");
2564 else if (element.fixed)
2565 fprintf(stream, ";\t///< Fixed optional value=\"%s\".\n", element.fixed);
2566 else if (!fake_union && minOccurs && !strcmp(minOccurs, "0") && (!maxOccurs || !strcmp(maxOccurs, "1")))
2567 fprintf(stream, ";\t///< Optional element.\n");
2568 else
2569 fprintf(stream, ";\n");
2570 }
2571 }
2572
2573 void Types::gen(const char *URI, const vector<xs__group>& groups)
2574 { for (vector<xs__group>::const_iterator group = groups.begin(); group != groups.end(); ++group)
2575 gen(URI, *group, NULL, NULL);
2576 }
2577
2578 void Types::gen(const char *URI, const xs__group& group, const char *minOccurs, const char *maxOccurs)
2579 { if (group.minOccurs)
2580 minOccurs = group.minOccurs;
2581 if (group.maxOccurs)
2582 maxOccurs = group.maxOccurs;
2583 if (group.groupPtr())
2584 { if (group.schemaPtr() == group.groupPtr()->schemaPtr())
2585 gen(URI, *group.groupPtr(), minOccurs, maxOccurs);
2586 else
2587 gen(group.groupPtr()->schemaPtr()->targetNamespace, *group.groupPtr(), minOccurs, maxOccurs);
2588 }
2589 else
2590 { fprintf(stream, "/// GROUP <xs:group name=\"%s\"", group.name ? group.name : "");
2591 if (minOccurs)
2592 fprintf(stream, " minOccurs=\"%s\"", minOccurs);
2593 if (maxOccurs)
2594 fprintf(stream, " maxOccurs=\"%s\"", maxOccurs);
2595 fprintf(stream, ">\n");
2596 document(group.annotation);
2597 if (group.all)
2598 gen(URI, *group.all, minOccurs, maxOccurs);
2599 else if (group.choice)
2600 gen(URI, NULL, *group.choice, minOccurs, maxOccurs);
2601 else if (group.sequence)
2602 gen(URI, *group.sequence, minOccurs, maxOccurs);
2603 fprintf(stream, "// END OF GROUP\n");
2604 }
2605 }
2606
2607 void Types::gen(const char *URI, const char *name, const xs__seqchoice& choice, const char *minOccurs, const char *maxOccurs)
2608 { const char *r = NULL, *s = NULL, *t = NULL;
2609 bool use_union = !uflag;
2610 bool wrap_union = false;
2611 bool tmp_union;
2612 if (!URI && choice.schemaPtr())
2613 URI = choice.schemaPtr()->targetNamespace;
2614 fprintf(stream, "/// CHOICE <xs:choice");
2615 if (choice.minOccurs)
2616 minOccurs = choice.minOccurs;
2617 if (choice.maxOccurs)
2618 maxOccurs = choice.maxOccurs;
2619 if (minOccurs)
2620 fprintf(stream, " minOccurs=\"%s\"", minOccurs);
2621 if (maxOccurs)
2622 fprintf(stream, " maxOccurs=\"%s\"", maxOccurs);
2623 fprintf(stream, ">\n");
2624 document(choice.annotation);
2625 for (vector<xs__contents>::const_iterator c1 = choice.__contents.begin(); c1 != choice.__contents.end(); ++c1)
2626 { if ((*c1).__union == SOAP_UNION_xs__union_content_group
2627 || (*c1).__union == SOAP_UNION_xs__union_content_sequence)
2628 { fprintf(stream, "/// Note: <xs:choice> with embedded <xs:sequence> or <xs:group> prevents the use of a union\n");
2629 use_union = false;
2630 break;
2631 }
2632 }
2633 if (use_union && (cflag || sflag))
2634 { for (vector<xs__contents>::const_iterator c2 = choice.__contents.begin(); c2 != choice.__contents.end(); ++c2)
2635 { if ((*c2).__union == SOAP_UNION_xs__union_content_element
2636 && (*c2).__content.element
2637 && (*c2).__content.element->maxOccurs
2638 && strcmp((*c2).__content.element->maxOccurs, "1"))
2639 { fprintf(stream, "/// Note: <xs:choice> of element with maxOccurs>1 prevents the use of a union\n");
2640 use_union = false;
2641 break;
2642 }
2643 }
2644 }
2645 t = uname(URI);
2646 s = strstr(t, "__union");
2647 if (s)
2648 r = s + 7;
2649 if (!r || !*r)
2650 { r = t;
2651 s = "__union";
2652 }
2653 if (maxOccurs && strcmp(maxOccurs, "1"))
2654 { if (with_union)
2655 { // Generate a wrapper when we need a union within a union
2656 wrap_union = true;
2657 fprintf(stream, " struct __%s\n {\n", t);
2658 }
2659 fprintf(stream, sizeformat, "int", r);
2660 fprintf(stream, " %s", minOccurs ? minOccurs : "0");
2661 if (is_integer(maxOccurs))
2662 fprintf(stream, ":%s", maxOccurs);
2663 fprintf(stream, ";\n");
2664 if (cflag)
2665 fprintf(stream, " struct _%s\n {\n", t);
2666 else
2667 fprintf(stream, " class _%s\n {\n", t);
2668 }
2669 if (use_union)
2670 { if (!with_union || wrap_union)
2671 { fprintf(stream, choiceformat, "int", r);
2672 if (minOccurs)
2673 fprintf(stream, " %s", minOccurs);
2674 fprintf(stream, ";\t///< Union %s selector: set to SOAP_UNION_%s_<fieldname>%s\n", t, t, minOccurs && !strcmp(minOccurs, "0") ? " or 0" : "");
2675 if (name)
2676 fprintf(stream, "/// Union for choice in type %s\n", cname(NULL, URI, name));
2677 fprintf(stream, " union %s\n {\n", t);
2678 }
2679 tmp_union = with_union;
2680 with_union = true;
2681 }
2682 else
2683 { tmp_union = fake_union;
2684 fake_union = true;
2685 }
2686 gen(URI, choice.__contents);
2687 if (use_union)
2688 { with_union = tmp_union;
2689 if (!with_union || wrap_union)
2690 fprintf(stream, elementformat, "}", s+2);
2691 }
2692 else
2693 fake_union = tmp_union;
2694 if (maxOccurs && strcmp(maxOccurs, "1"))
2695 { if (use_union)
2696 fprintf(stream, ";\n");
2697 fprintf(stream, pointerformat, "}", s);
2698 }
2699 fprintf(stream, ";\n");
2700 if (wrap_union)
2701 { fprintf(stream, elementformat, "}", s);
2702 fprintf(stream, ";\n");
2703 }
2704 fprintf(stream, "// END OF CHOICE\n");
2705 }
2706
2707 void Types::gen(const char *URI, const vector<xs__any>& anys)
2708 { for (vector<xs__any>::const_iterator any = anys.begin(); any != anys.end(); ++any)
2709 gen(URI, *any, NULL, NULL);
2710 }
2711
2712 void Types::gen(const char *URI, const xs__any& any, const char *minOccurs, const char *maxOccurs)
2713 { fprintf(stream, "/// TODO: <any");
2714 if (any.namespace_)
2715 fprintf(stream, " namespace=\"%s\"", any.namespace_);
2716 if (any.minOccurs)
2717 minOccurs = any.minOccurs;
2718 if (any.maxOccurs)
2719 maxOccurs = any.maxOccurs;
2720 if (minOccurs)
2721 fprintf(stream, " minOccurs=\"%s\"", minOccurs);
2722 if (maxOccurs)
2723 fprintf(stream, " maxOccurs=\"%s\"", maxOccurs);
2724 fprintf(stream, ">\n/// TODO: Schema extensibility is user-definable.\n/// Consult the protocol documentation to change or insert declarations.\n/// Use wsdl2h option -x to remove this element.\n/// Use wsdl2h option -d for xsd__anyType DOM (soap_dom_element).\n");
2725 if (!xflag)
2726 { if (maxOccurs && strcmp(maxOccurs, "1"))
2727 { fprintf(stream, "/// Size of the array of XML or DOM nodes is %s..%s\n", minOccurs ? minOccurs : "1", maxOccurs);
2728 if (cflag || sflag)
2729 { if (!with_union)
2730 { fprintf(stream, sizeformat, "int", "");
2731 fprintf(stream, "0;\n");
2732 fprintf(stream, elementformat, pname(true, NULL, NULL, "xsd:any"), "__any");
2733 }
2734 else
2735 fprintf(stream, elementformat, tname(NULL, NULL, "xsd:any"), "__any");
2736 }
2737 else if (with_union)
2738 fprintf(stream, pointervectorformat, tname(NULL, NULL, "xsd:any"), "__any");
2739 else
2740 fprintf(stream, vectorformat, tname(NULL, NULL, "xsd:any"), "__any");
2741 }
2742 else
2743 fprintf(stream, elementformat, pname(with_union, NULL, NULL, "xsd:any"), "__any");
2744 if (dflag)
2745 fprintf(stream, "0;\t///< Catch any element content in DOM.\n");
2746 else
2747 fprintf(stream, "0;\t///< Catch any element content in XML string.\n");
2748 }
2749 }
2750
2751 void Types::gen(const char *URI, const xs__anyAttribute& anyAttribute)
2752 { if (anyAttribute.namespace_)
2753 fprintf(stream, "/// <anyAttribute namespace=\"%s\">\n", anyAttribute.namespace_);
2754 fprintf(stream, "/// TODO: Schema extensibility is user-definable.\n/// Consult the protocol documentation to change or insert declarations.\n/// Use wsdl2h option -x to remove this attribute.\n/// Use wsdl2h option -d for xsd__anyAttribute DOM (soap_dom_attribute).\n");
2755 if (!xflag)
2756 { const char *t = tname(NULL, NULL, "xsd:anyAttribute");
2757 fprintf(stream, attributeformat, t, "__anyAttribute");
2758 if (dflag)
2759 fprintf(stream, ";\t///< Store anyAttribute content in DOM soap_dom_attribute linked node structure.\n");
2760 else
2761 fprintf(stream, ";\t///< A placeholder that has no effect: please see comment.\n");
2762 }
2763 }
2764
2765 void Types::gen_inh(const char *URI, const xs__complexType *complexType, bool anonymous)
2766 { const xs__complexType *p = complexType;
2767 if (!p)
2768 return;
2769 const char *pURI;
2770 if (p->schemaPtr())
2771 pURI = p->schemaPtr()->targetNamespace;
2772 else
2773 pURI = URI;
2774 const char *b = cname(NULL, pURI, p->name);
2775 if (p->complexContent && p->complexContent->extension)
2776 gen_inh(URI, p->complexContent->extension->complexTypePtr(), anonymous);
2777 if (cflag || fflag || anonymous)
2778 fprintf(stream, "/// INHERITED FROM %s:\n", b);
2779 else if (comment_nest == 0)
2780 fprintf(stream, "/* INHERITED FROM %s:\n", b);
2781 else
2782 fprintf(stream, " INHERITED FROM %s:\n", b);
2783 comment_nest++;
2784 if (cflag || fflag)
2785 pURI = URI; // if base ns != derived ns then qualify elts
2786 if (p->complexContent && p->complexContent->extension)
2787 { if (p->complexContent->extension->group)
2788 gen(pURI, *p->complexContent->extension->group, NULL, NULL);
2789 if (p->complexContent->extension->all)
2790 gen(pURI, *p->complexContent->extension->all, NULL, NULL);
2791 if (p->complexContent->extension->sequence)
2792 gen(pURI, *p->complexContent->extension->sequence, NULL, NULL);
2793 if (p->complexContent->extension->choice)
2794 gen(pURI, p->name, *p->complexContent->extension->choice, NULL, NULL);
2795 gen(pURI, p->complexContent->extension->attribute);
2796 gen(pURI, p->complexContent->extension->attributeGroup);
2797 if (p->complexContent->extension->anyAttribute)
2798 gen(pURI, *p->complexContent->extension->anyAttribute);
2799 }
2800 else
2801 { if (p->all)
2802 gen(pURI, p->all->element, NULL, NULL);
2803 else if (p->all)
2804 gen(pURI, *p->all, NULL, NULL);
2805 else if (p->choice)
2806 gen(pURI, p->name, *p->choice, NULL, NULL);
2807 else if (p->sequence)
2808 gen(pURI, *p->sequence, NULL, NULL);
2809 else if (p->any)
2810 gen(pURI, *p->any, NULL, NULL);
2811 gen(pURI, p->attribute);
2812 gen(pURI, p->attributeGroup);
2813 if (p->anyAttribute)
2814 gen(pURI, *p->anyAttribute);
2815 }
2816 modify(b);
2817 comment_nest--;
2818 if (cflag || fflag || anonymous)
2819 fprintf(stream, "// END OF INHERITED FROM %s\n", b);
2820 else if (comment_nest == 0)
2821 fprintf(stream, " END OF INHERITED FROM %s */\n", b);
2822 else
2823 fprintf(stream, " END OF INHERITED FROM %s\n", b);
2824 }
2825
2826 void Types::gen_soap_array(const char *name, const char *t, const char *item, const char *type)
2827 { char *tmp = NULL, *dims = NULL, size[8];
2828 if (type)
2829 { tmp = (char*)emalloc(strlen(type) + 1);
2830 strcpy(tmp, type);
2831 }
2832 *size = '\0';
2833 if (tmp)
2834 dims = strrchr(tmp, '[');
2835 if (dims)
2836 *dims++ = '\0';
2837 fprintf(stream, "/// SOAP encoded array of %s\n", tmp ? tmp : "xs:anyType");
2838 if (cflag)
2839 fprintf(stream, "struct %s\n{\n", t);
2840 else if (pflag)
2841 fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t);
2842 else
2843 fprintf(stream, "class %s\n{ public:\n", t);
2844 if (dims)
2845 { char *s = strchr(dims, ']');
2846 if (s && s != dims)
2847 sprintf(size, "[%d]", (int)(s - dims + 1));
2848 }
2849 if (tmp)
2850 { if (strchr(tmp, '[') != NULL)
2851 { gen_soap_array(NULL, "", item, tmp);
2852 fprintf(stream, arrayformat, "}", item ? aname(NULL, NULL, item) : "");
2853 fprintf(stream, ";\n");
2854 }
2855 else
2856 { const char *s = pname(!is_basetype(NULL, NULL, tmp), NULL, NULL, tmp);
2857 fprintf(stream, "/// Pointer to array of %s.\n", s);
2858 fprintf(stream, arrayformat, s, item ? aname(NULL, NULL, item) : "");
2859 fprintf(stream, ";\n");
2860 }
2861 if (*size)
2862 fprintf(stream, "/// Size of the multidimensional dynamic array with dimensions=%s\n", size);
2863 else
2864 fprintf(stream, "/// Size of the dynamic array.\n");
2865 fprintf(stream, arraysizeformat, "int", size);
2866 fprintf(stream, ";\n/// Offset for partially transmitted arrays (uncomment only when required).\n");
2867 fprintf(stream, arrayoffsetformat, "int", size);
2868 fprintf(stream, ";\n");
2869 }
2870 else
2871 { // TODO: how to handle generic SOAP array? E.g. as an array of anyType?
2872 fprintf(stream, "// TODO: add declarations to handle generic SOAP-ENC:Array (array of anyType)\n");
2873 }
2874 }
2875
2876 void Types::gen_substitutions(const char *URI, const xs__element &element)
2877 { const std::vector<xs__element*> *substitutions;
2878 const char *name;
2879 const char *r = NULL, *s = NULL;
2880 bool use_union = !uflag;
2881 bool wrap_union = false;
2882 bool tmp_union;
2883 bool abstract = false;
2884 if (!URI && element.schemaPtr())
2885 URI = element.schemaPtr()->targetNamespace;
2886 if (element.elementPtr())
2887 { name = element.elementPtr()->name;
2888 substitutions = element.elementPtr()->substitutionsPtr();
2889 abstract = element.elementPtr()->abstract;
2890 if (!abstract && element.elementPtr()->complexTypePtr())
2891 abstract = element.elementPtr()->complexTypePtr()->abstract;
2892 }
2893 else
2894 { name = element.name;
2895 substitutions = element.substitutionsPtr();
2896 abstract = element.abstract;
2897 if (!abstract && element.complexTypePtr())
2898 abstract = element.complexTypePtr()->abstract;
2899 }
2900 fprintf(stream, "/// CHOICE OF SUBSTITUTIONS <xs:element substitutionGroup=\"%s\"", name);
2901 if (element.minOccurs)
2902 fprintf(stream, " minOccurs=\"%s\"", element.minOccurs);
2903 if (element.maxOccurs)
2904 fprintf(stream, " maxOccurs=\"%s\"", element.maxOccurs);
2905 fprintf(stream, "> with elements");
2906 for (std::vector<xs__element*>::const_iterator i1 = substitutions->begin(); i1 != substitutions->end(); ++i1)
2907 fprintf(stream, " <%s>", (*i1)->name);
2908 fprintf(stream, "\n");
2909 if (use_union)
2910 { const char *t = uname(URI);
2911 // TODO: could reuse the union instead of generating a new one each time!
2912 s = strstr(t, "__union");
2913 if (!s)
2914 s = "__union";
2915 r = aname(NULL, NULL, name);
2916 if (element.maxOccurs && strcmp(element.maxOccurs, "1"))
2917 { if (with_union)
2918 { // Generate a wrapper when we need a union within a union
2919 wrap_union = true;
2920 fprintf(stream, " struct __%s\n {\n", t);
2921 }
2922 fprintf(stream, sizeformat, "int", r);
2923 fprintf(stream, " %s", element.minOccurs ? element.minOccurs : "0");
2924 if (is_integer(element.maxOccurs))
2925 fprintf(stream, ":%s", element.maxOccurs);
2926 fprintf(stream, ";\n");
2927 if (cflag)
2928 fprintf(stream, " struct _%s\n {\n", t);
2929 else
2930 fprintf(stream, " class _%s\n {\n", t);
2931 }
2932 if (!with_union || wrap_union)
2933 { fprintf(stream, choiceformat, "int", r);
2934 fprintf(stream, " %s", element.minOccurs ? element.minOccurs : "0");
2935 fprintf(stream, ";\t///< Union %s selector: set to SOAP_UNION_%s_<fieldname>%s\n", t, t, element.minOccurs && !strcmp(element.minOccurs, "0") ? " or 0" : "");
2936 fprintf(stream, "/// Union for substitutionGroup=\"%s\"\n", name);
2937 fprintf(stream, " union %s\n {\n", t);
2938 }
2939 tmp_union = with_union;
2940 with_union = true;
2941 }
2942 else
2943 { tmp_union = fake_union;
2944 fake_union = true;
2945 }
2946 if (!abstract)
2947 gen(URI, element, false, NULL, NULL);
2948 for (vector<xs__element*>::const_iterator i2 = substitutions->begin(); i2 != substitutions->end(); ++i2)
2949 gen(URI, *(*i2), true, NULL, NULL); // substitutions are recursive?
2950 if (use_union)
2951 { with_union = tmp_union;
2952 if (!with_union || wrap_union)
2953 { fprintf(stream, elementformat, "}", s);
2954 fprintf(stream, ";\n");
2955 }
2956 if (element.maxOccurs && strcmp(element.maxOccurs, "1"))
2957 { fprintf(stream, ";\n");
2958 fprintf(stream, pointerformat, "}", s);
2959 fprintf(stream, ";\n");
2960 }
2961 if (wrap_union)
2962 { fprintf(stream, elementformat, "}", s);
2963 fprintf(stream, ";\n");
2964 }
2965 }
2966 else
2967 fake_union = tmp_union;
2968 fprintf(stream, "// END OF CHOICE OF SUBSTITUTIONS\n");
2969 }
2970
2971 void Types::document(const xs__annotation *annotation)
2972 { if (annotation && annotation->documentation)
2973 { fprintf(stream, "/// @brief");
2974 documentation(annotation->documentation);
2975 }
2976 }
2977
2978 void Types::modify(const char *name)
2979 { // TODO: consider support removal of elements/attributes with ns__X = $- Y
2980 const char *s = modtypemap[name];
2981 if (s)
2982 { while (*s)
2983 { if (*s++ == '$')
2984 fprintf(stream, "/// Member declared in %s\n ", mapfile);
2985 s = format(s);
2986 }
2987 }
2988 }
2989
2990 const char* Types::format(const char *text)
2991 { const char *s = text;
2992 if (!s)
2993 return NULL;
2994 while (*s && *s != '$')
2995 { if (*s == '\\')
2996 { switch (s[1])
2997 { case 'n':
2998 fputc('\n', stream);
2999 break;
3000 case 't':
3001 fputc('\t', stream);
3002 break;
3003 default:
3004 fputc(s[1], stream);
3005 }
3006 s++;
3007 }
3008 else
3009 fputc(*s, stream);
3010 s++;
3011 }
3012 fputc('\n', stream);
3013 return s;
3014 }
3015
3016 ////////////////////////////////////////////////////////////////////////////////
3017 //
3018 // Type map file parsing
3019 //
3020 ////////////////////////////////////////////////////////////////////////////////
3021
3022 static char *getline(char *s, size_t n, FILE *fd)
3023 { int c;
3024 char *t = s;
3025 if (n)
3026 n--;
3027 for (;;)
3028 { c = fgetc(fd);
3029 if (c == '\r')
3030 continue;
3031 if (c == '\\')
3032 { c = fgetc(fd);
3033 if (c == '\r')
3034 c = fgetc(fd);
3035 if (c < ' ')
3036 continue;
3037 if (n)
3038 { *t++ = '\\';
3039 n--;
3040 }
3041 }
3042 if (c == '\n' || c == EOF)
3043 break;
3044 if (n)
3045 { *t++ = c;
3046 n--;
3047 }
3048 }
3049 *t++ = '\0';
3050 if (!*s && c == EOF)
3051 return NULL;
3052 return s;
3053 }
3054
3055 static const char *nonblank(const char *s)
3056 { while (*s && isspace(*s))
3057 s++;
3058 return s;
3059 }
3060
3061 static const char *fill(char *t, int n, const char *s, int e)
3062 { int i = n;
3063 s = nonblank(s);
3064 while (*s && *s != e && --i)
3065 *t++ = *s++;
3066 while (*s && *s != e)
3067 s++;
3068 if (*s)
3069 s++;
3070 i = n - i;
3071 if (i == 0)
3072 *t = '\0';
3073 else
3074 { while (isspace(*--t) && i--)
3075 ;
3076 t[1] = '\0';
3077 }
3078 return s;
3079 }
3080
3081 ////////////////////////////////////////////////////////////////////////////////
3082 //
3083 // Miscellaneous
3084 //
3085 ////////////////////////////////////////////////////////////////////////////////
3086
3087 static const char *utf8(char *t, const char *s)
3088 { unsigned int c = 0;
3089 unsigned int c1, c2, c3, c4;
3090 c = (unsigned char)*s;
3091 if (c >= 0x80)
3092 { c1 = (unsigned char)*++s;
3093 if (c1 < 0x80)
3094 s--;
3095 else
3096 { c1 &= 0x3F;
3097 if (c < 0xE0)
3098 c = ((c & 0x1F) << 6) | c1;
3099 else
3100 { c2 = (unsigned char)*++s & 0x3F;
3101 if (c < 0xF0)
3102 c = ((c & 0x0F) << 12) | (c1 << 6) | c2;
3103 else
3104 { c3 = (unsigned char)*++s & 0x3F;
3105 if (c < 0xF8)
3106 c = ((c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
3107 else
3108 { c4 = (unsigned char)*++s & 0x3F;
3109 if (c < 0xFC)
3110 c = ((c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
3111 else
3112 c = ((c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (*++s & 0x3F);
3113 }
3114 }
3115 }
3116 }
3117 }
3118 sprintf(t, "_x%.4x", c);
3119 return s;
3120 }
3121
3122 static const char *cstring(const char *s)
3123 { size_t n;
3124 char *t;
3125 const char *r;
3126 for (n = 0, r = s; *r; n++, r++)
3127 if (*r == '"' || *r == '\\')
3128 n++;
3129 else if (*r < 32)
3130 n += 3;
3131 r = t = (char*)emalloc(n + 1);
3132 for (; *s; s++)
3133 { if (*s == '"' || *s == '\\')
3134 { *t++ = '\\';
3135 *t++ = *s;
3136 }
3137 else if (*s < 32)
3138 { sprintf(t, "\\%03o", (unsigned int)(unsigned char)*s);
3139 t += 4;
3140 }
3141 else
3142 *t++ = *s;
3143 }
3144 *t = '\0';
3145 return r;
3146 }
3147
3148 static const char *xstring(const char *s)
3149 { size_t n;
3150 char *t;
3151 const char *r;
3152 for (n = 0, r = s; *r; n++, r++)
3153 { if (*r < 32 || *r >= 127)
3154 n += 4;
3155 else if (*r == '<' || *r == '>')
3156 n += 3;
3157 else if (*r == '&')
3158 n += 4;
3159 else if (*r == '"')
3160 n += 5;
3161 else if (*r == '\\')
3162 n += 1;
3163 }
3164 r = t = (char*)emalloc(n + 1);
3165 for (; *s; s++)
3166 { if (*s < 32 || *s >= 127)
3167 { sprintf(t, "&#%.2x;", (unsigned char)*s);
3168 t += 5;
3169 }
3170 else if (*s == '<')
3171 { strcpy(t, "&lt;");
3172 t += 4;
3173 }
3174 else if (*s == '>')
3175 { strcpy(t, "&gt;");
3176 t += 4;
3177 }
3178 else if (*s == '&')
3179 { strcpy(t, "&amp;");
3180 t += 5;
3181 }
3182 else if (*s == '"')
3183 { strcpy(t, "&quot;");
3184 t += 6;
3185 }
3186 else if (*s == '\\')
3187 { strcpy(t, "\\\\");
3188 t += 2;
3189 }
3190 else
3191 *t++ = *s;
3192 }
3193 *t = '\0';
3194 return r;
3195 }
3196
3197 static LONG64 to_integer(const char *s)
3198 { LONG64 n;
3199 #ifdef HAVE_STRTOLL
3200 char *r;
3201 n = soap_strtoll(s, &r, 10);
3202 #else
3203 # ifdef HAVE_SSCANF
3204 sscanf(s, SOAP_LONG_FORMAT, &n);
3205 # endif
3206 #endif
3207 return n;
3208 }
3209
3210 static bool is_integer(const char *s)
3211 { if ((*s == '-' || *s == '+') && s[1])
3212 s++;
3213 if (!*s || strlen(s) > 20)
3214 return false;
3215 while (*s && isdigit(*s))
3216 s++;
3217 return *s == '\0';
3218 }
3219
3220 static void documentation(const char *text)
3221 { const char *s = text;
3222 bool flag = true;
3223 if (!s)
3224 return;
3225 while (*s)
3226 { switch (*s)
3227 { case '\n':
3228 case '\t':
3229 case ' ':
3230 flag = true;
3231 break;
3232 default:
3233 if (*s > 32)
3234 { if (flag)
3235 { fputc(' ', stream);
3236 flag = false;
3237 }
3238 fputc(*s, stream);
3239 }
3240 }
3241 s++;
3242 }
3243 fputc('\n', stream);
3244 }
3245
3246 static void operations(const char *t)
3247 { if (!cflag)
3248 fprintf(stream, "/// class %s operations:\n/// - soap_new_%s(soap*) allocate\n/// - soap_new_%s(soap*, int num) allocate array\n/// - soap_new_req_%s(soap*, ...) allocate, set required members\n/// - soap_new_set_%s(soap*, ...) allocate, set all public members\n/// - int soap_read_%s(soap*, %s*) deserialize from a stream\n/// - int soap_write_%s(soap, %s*) serialize to a stream\n", t, t, t, t, t, t, t, t, t);
3249 }
3250
3251 ////////////////////////////////////////////////////////////////////////////////
3252 //
3253 // Allocation
3254 //
3255 ////////////////////////////////////////////////////////////////////////////////
3256
3257 void *emalloc(size_t size)
3258 { void *p = malloc(size);
3259 if (!p)
3260 { fprintf(stderr, "\nError: Malloc failed\n");
3261 exit(1);
3262 }
3263 return p;
3264 }
3265
3266 char *estrdup(const char *s)
3267 { char *t = (char*)emalloc(strlen(s) + 1);
3268 strcpy(t, s);
3269 return t;
3270 }
3271
3272 char *estrdupf(const char *s)
3273 { char *t = (char*)emalloc(strlen(s) + 1);
3274 char *p;
3275 for (p = t; *s; s++)
3276 { if (s[0] == '/' && s[1] == '*')
3277 { for (s += 2; s[0] && s[1]; s++)
3278 { if (s[0] == '*' && s[1] == '/')
3279 { s++;
3280 break;
3281 }
3282 }
3283 continue;
3284 }
3285 *p++ = *s;
3286 }
3287 *p = '\0';
3288 return t;
3289 }