Mercurial > repos > ktnyt > gembassy
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, "<"); | |
3172 t += 4; | |
3173 } | |
3174 else if (*s == '>') | |
3175 { strcpy(t, ">"); | |
3176 t += 4; | |
3177 } | |
3178 else if (*s == '&') | |
3179 { strcpy(t, "&"); | |
3180 t += 5; | |
3181 } | |
3182 else if (*s == '"') | |
3183 { strcpy(t, """); | |
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 } |