0
|
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 }
|