~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to tools/gsoap/gsoap-linux-2.7/wsdl/.svn/text-base/types.cpp.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

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