Mercurial > repos > ktnyt > gembassy
diff GEMBASSY-1.0.3/gsoap/wsdl/types.cpp @ 2:8947fca5f715 draft default tip
Uploaded
author | ktnyt |
---|---|
date | Fri, 26 Jun 2015 05:21:44 -0400 |
parents | 84a17b3fad1f |
children |
line wrap: on
line diff
--- a/GEMBASSY-1.0.3/gsoap/wsdl/types.cpp Fri Jun 26 05:20:29 2015 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3289 +0,0 @@ -/* - types.cpp - - Generate gSOAP types from XML schemas (e.g. embedded in WSDL). - --------------------------------------------------------------------------------- -gSOAP XML Web services tools -Copyright (C) 2001-2013, Robert van Engelen, Genivia Inc. All Rights Reserved. -This software is released under one of the following licenses: -GPL or Genivia's license for commercial use. --------------------------------------------------------------------------------- -GPL license. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -Author contact information: -engelen@genivia.com / engelen@acm.org --------------------------------------------------------------------------------- -A commercial use license is available from Genivia, Inc., contact@genivia.com --------------------------------------------------------------------------------- - -*/ - -#include "types.h" - -static char *getline(char *s, size_t n, FILE *fd); -static const char *nonblank(const char *s); -static const char *fill(char *t, int n, const char *s, int e); -static const char *utf8(char *t, const char *s); -static const char *cstring(const char *s); -static const char *xstring(const char *s); -static bool is_integer(const char *s); -static LONG64 to_integer(const char *s); -static void documentation(const char *text); -static void operations(const char *t); - -static int comment_nest = 0; /* keep track of block comments to avoid nesting */ - -//////////////////////////////////////////////////////////////////////////////// -// -// Keywords and reserved words -// -//////////////////////////////////////////////////////////////////////////////// - -static const char *keywords[] = -{ "and", - "asm", - "auto", - "bool", - "break", - "case", - "catch", - "char", - "class", - "const", - "const_cast", - "continue", - "default", - "delete", - "do", - "double", - "dynamic_cast", - "else", - "enum", - "errno", - "explicit", - "export", - "extern", - "false", - "FILE", - "float", - "for", - "friend", - "goto", - "if", - "inline", - "int", - "interface", - "long", - "LONG64", - "max", - "min", - "mustUnderstand", - "mutable", - "namespace", - "new", - "not", - "NULL", - "operator", - "or", - "private", - "protected", - "public", - "_QName", - "register", - "reinterpret_cast", - "restrict", - "return", - "short", - "signed", - "size_t", - "sizeof", - "soap", - "static", - "static_cast", - "struct", - "switch", - "template", - "this", - "throw", - "time_t", - "true", - "typedef", - "typeid", - "typeof", - "typename", - "ULONG64", - "union", - "unsigned", - "using", - "virtual", - "void", - "volatile", - "wchar_t", - "while", - "XML", - "_XML", - "xor", -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// Types methods -// -//////////////////////////////////////////////////////////////////////////////// - -Types::Types() -{ init(); -} - -int Types::read(const char *file) -{ FILE *fd; - char buf[1024], xsd[1024], def[1024], use[1024], ptr[1024], uri[1024]; - const char *s; - short copy = 0; - strcpy(buf, file); - fd = fopen(buf, "r"); - if (!fd && import_path) - { strcpy(buf, import_path); - strcat(buf, "/"); - strcat(buf, file); - fd = fopen(buf, "r"); - } - if (!fd) - { fprintf(stderr, "Cannot open file '%s'\n", buf); - return SOAP_EOF; - } - fprintf(stderr, "Reading type definitions from type map file '%s'\n", buf); - while (getline(buf, sizeof(buf), fd)) - { s = buf; - if (copy) - { if (*s == ']') - copy = 0; - else - fprintf(stream, "%s\n", buf); - } - else if (*s == '[') - copy = 1; - else if (*s == '<') - { s = fill(uri, sizeof(uri), s+1, -1); - infile[infiles++] = estrdup(uri); - if (infiles >= MAXINFILES) - { fprintf(stderr, "wsdl2h: too many files\n"); - exit(1); - } - } - else if (*s == '>') - { s = fill(uri, sizeof(uri), s+1, -1); - if (!outfile) - { outfile = estrdup(uri); - stream = fopen(outfile, "w"); - if (!stream) - { fprintf(stderr, "Cannot write to %s\n", outfile); - exit(1); - } - if (cppnamespace) - fprintf(stream, "namespace %s {\n", cppnamespace); - fprintf(stderr, "Saving %s\n\n", outfile); - } - } - else if (*s && *s != '#') - { s = fill(xsd, sizeof(xsd), s, '='); - if (strstr(xsd, "__")) - { if (s && *s == '=') - { s = fill(use, sizeof(use), s+1, '|'); - if (*xsd && *use) - { s = estrdup(xsd); - eqvtypemap[s] = estrdup(use); - } - } - else - { s = fill(def, sizeof(def), s, '|'); - s = fill(use, sizeof(use), s, '|'); - s = fill(ptr, sizeof(ptr), s, '|'); - if (*xsd) - { s = estrdup(xsd); - if (*def == '$') - { const char *t = modtypemap[s]; - if (t) - { char *r = (char*)emalloc(strlen(t) + strlen(def) + 1); - strcpy(r, t); - strcat(r, def); - free((void*)modtypemap[s]); - modtypemap[s] = r; - } - else - modtypemap[s] = estrdup(def); - } - else - { if (*def) - { if (strcmp(def, "...")) - deftypemap[s] = estrdup(def); - } - else - deftypemap[s] = ""; - if (*use) - usetypemap[s] = estrdupf(use); - else - usetypemap[s] = estrdupf(xsd); - if (*ptr) - ptrtypemap[s] = estrdupf(ptr); - } - } - } - } - else if (*xsd) - { s = fill(uri, sizeof(uri), s, 0); - if (uri[0] == '"') - { uri[strlen(uri) - 1] = '\0'; - nsprefix(xsd, estrdup(uri + 1)); - } - else if (uri[0] == '<') - { uri[strlen(uri) - 1] = '\0'; - char *s = estrdup(uri + 1); - nsprefix(xsd, s); - exturis.insert(s); - } - else - nsprefix(xsd, estrdup(uri)); - } - } - } - fclose(fd); - return SOAP_OK; -} - -void Types::init() -{ snum = 1; - unum = 1; - gnum = 1; - with_union = false; - fake_union = false; - knames.insert(keywords, keywords + sizeof(keywords)/sizeof(char*)); - if (cflag) - { deftypemap["xsd__ur_type"] = ""; - if (dflag) - { usetypemap["xsd__ur_type"] = "xsd__anyType"; - ptrtypemap["xsd__ur_type"] = "xsd__anyType*"; - } - else - { usetypemap["xsd__ur_type"] = "_XML"; - ptrtypemap["xsd__ur_type"] = "_XML"; - } - } - else - { deftypemap["xsd__ur_type"] = "class xsd__ur_type { _XML __item; struct soap *soap; };"; - usetypemap["xsd__ur_type"] = "xsd__ur_type"; - } - if (cflag) - { deftypemap["xsd__anyType"] = ""; - if (dflag) - { usetypemap["xsd__anyType"] = "xsd__anyType"; - ptrtypemap["xsd__anyType"] = "xsd__anyType*"; - } - else - { usetypemap["xsd__anyType"] = "_XML"; - ptrtypemap["xsd__anyType"] = "_XML"; - } - } - else - { if (dflag) - { deftypemap["xsd__anyType"] = ""; - usetypemap["xsd__anyType"] = "xsd__anyType"; - ptrtypemap["xsd__anyType"] = "xsd__anyType*"; - } - else - { deftypemap["xsd__anyType"] = "class xsd__anyType { _XML __item; struct soap *soap; };"; - usetypemap["xsd__anyType"] = "xsd__anyType*"; - } - } - deftypemap["xsd__any"] = ""; - if (dflag) - { usetypemap["xsd__any"] = "xsd__anyType"; - ptrtypemap["xsd__any"] = "xsd__anyType*"; - } - else - { usetypemap["xsd__any"] = "_XML"; - ptrtypemap["xsd__any"] = "_XML"; - } - deftypemap["xsd__anyAttribute"] = ""; - if (dflag) - { usetypemap["xsd__anyAttribute"] = "xsd__anyAttribute"; - ptrtypemap["xsd__anyAttribute"] = "xsd__anyAttribute*"; - } - else - { usetypemap["xsd__anyAttribute"] = "_XML"; - ptrtypemap["xsd__anyAttribute"] = "_XML"; - } - if (cflag) - { deftypemap["xsd__base64Binary"] = "struct xsd__base64Binary\n{\tunsigned char *__ptr;\n\tint __size;\n\tchar *id, *type, *options; // NOTE: non-NULL for DIMEM/MIME/MTOM XOP attachments only\n};"; - usetypemap["xsd__base64Binary"] = "struct xsd__base64Binary"; - } - else - { deftypemap["xsd__base64Binary"] = "class xsd__base64Binary\n{\tunsigned char *__ptr;\n\tint __size;\n\tchar *id, *type, *options; // NOTE: non-NULL for DIMEM/MIME/MTOM XOP attachments only\n\tstruct soap *soap;\n};"; - usetypemap["xsd__base64Binary"] = "xsd__base64Binary"; - } - if (cflag) - { if (eflag) - deftypemap["xsd__boolean"] = "enum xsd__boolean { false_, true_ };"; - else - deftypemap["xsd__boolean"] = "enum xsd__boolean { xsd__boolean__false_, xsd__boolean__true_ };"; - usetypemap["xsd__boolean"] = "enum xsd__boolean"; - } - else - { deftypemap["xsd__boolean"] = ""; - usetypemap["xsd__boolean"] = "bool"; - } - deftypemap["xsd__byte"] = "typedef char xsd__byte;"; - usetypemap["xsd__byte"] = "xsd__byte"; - deftypemap["xsd__dateTime"] = ""; - usetypemap["xsd__dateTime"] = "time_t"; - deftypemap["xsd__double"] = ""; - usetypemap["xsd__double"] = "double"; - deftypemap["xsd__float"] = ""; - usetypemap["xsd__float"] = "float"; - if (cflag) - { deftypemap["xsd__hexBinary"] = "struct xsd__hexBinary { unsigned char *__ptr; int __size; };"; - usetypemap["xsd__hexBinary"] = "struct xsd__hexBinary"; - } - else - { deftypemap["xsd__hexBinary"] = "class xsd__hexBinary { unsigned char *__ptr; int __size; };"; - usetypemap["xsd__hexBinary"] = "xsd__hexBinary"; - } - deftypemap["xsd__int"] = ""; - usetypemap["xsd__int"] = "int"; - deftypemap["xsd__long"] = ""; - usetypemap["xsd__long"] = "LONG64"; - deftypemap["xsd__short"] = ""; - usetypemap["xsd__short"] = "short"; - if (cflag || sflag) - { deftypemap["xsd__string"] = ""; - usetypemap["xsd__string"] = "char*"; - } - else - { deftypemap["xsd__string"] = ""; - usetypemap["xsd__string"] = "std::string"; - } - if (cflag || sflag) - { deftypemap["xsd__QName"] = ""; - usetypemap["xsd__QName"] = "_QName"; - ptrtypemap["xsd__QName"] = "_QName"; - } - else - { deftypemap["xsd__QName"] = "typedef std::string xsd__QName;"; - usetypemap["xsd__QName"] = "xsd__QName"; - } - deftypemap["xsd__unsignedByte"] = "typedef unsigned char xsd__unsignedByte;"; - usetypemap["xsd__unsignedByte"] = "xsd__unsignedByte"; - deftypemap["xsd__unsignedInt"] = ""; - usetypemap["xsd__unsignedInt"] = "unsigned int"; - deftypemap["xsd__unsignedLong"] = ""; - usetypemap["xsd__unsignedLong"] = "ULONG64"; - deftypemap["xsd__unsignedShort"] = ""; - usetypemap["xsd__unsignedShort"] = "unsigned short"; - if (cflag) - { deftypemap["SOAP_ENC__base64Binary"] = "struct SOAP_ENC__base64Binary { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__base64Binary"] = "struct SOAP_ENC__base64Binary"; - deftypemap["SOAP_ENC__base64"] = "struct SOAP_ENC__base64 { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__base64"] = "struct SOAP_ENC__base64"; - } - else - { deftypemap["SOAP_ENC__base64Binary"] = "class SOAP_ENC__base64Binary { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__base64Binary"] = "SOAP_ENC__base64Binary"; - deftypemap["SOAP_ENC__base64"] = "class SOAP_ENC__base64 { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__base64"] = "SOAP_ENC__base64"; - } - if (cflag) - { deftypemap["SOAP_ENC__boolean"] = "enum SOAP_ENC__boolean { false_, true_ };"; - usetypemap["SOAP_ENC__boolean"] = "enum SOAP_ENC__boolean"; - } - else - { deftypemap["SOAP_ENC__boolean"] = "typedef bool SOAP_ENC__boolean;"; - usetypemap["SOAP_ENC__boolean"] = "SOAP_ENC__boolean"; - } - deftypemap["SOAP_ENC__byte"] = "typedef char SOAP_ENC__byte;"; - usetypemap["SOAP_ENC__byte"] = "SOAP_ENC__byte"; - deftypemap["SOAP_ENC__dateTime"] = "typedef time_t SOAP_ENC__dateTime;"; - usetypemap["SOAP_ENC__dateTime"] = "SOAP_ENC__dateTime"; - deftypemap["SOAP_ENC__double"] = "typedef double SOAP_ENC__double;"; - usetypemap["SOAP_ENC__double"] = "SOAP_ENC__double"; - deftypemap["SOAP_ENC__float"] = "typedef float SOAP_ENC__float"; - usetypemap["SOAP_ENC__float"] = "SOAP_ENC__float"; - if (cflag) - { deftypemap["SOAP_ENC__hexBinary"] = "struct SOAP_ENC__hexBinary { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__hexBinary"] = "struct SOAP_ENC__hexBinary"; - } - else - { deftypemap["SOAP_ENC__hexBinary"] = "class SOAP_ENC__hexBinary { unsigned char *__ptr; int __size; };"; - usetypemap["SOAP_ENC__hexBinary"] = "SOAP_ENC__hexBinary"; - } - deftypemap["SOAP_ENC__int"] = "typedef int SOAP_ENC__int;"; - usetypemap["SOAP_ENC__int"] = "SOAP_ENC__int"; - deftypemap["SOAP_ENC__long"] = "typedef LONG64 SOAP_ENC__long;"; - usetypemap["SOAP_ENC__long"] = "SOAP_ENC__long"; - deftypemap["SOAP_ENC__short"] = "typedef short SOAP_ENC__short;"; - usetypemap["SOAP_ENC__short"] = "SOAP_ENC__short"; - if (cflag || sflag) - { deftypemap["SOAP_ENC__string"] = ""; - usetypemap["SOAP_ENC__string"] = "char*"; - } - else - { deftypemap["SOAP_ENC__string"] = ""; - usetypemap["SOAP_ENC__string"] = "std::string"; - } - deftypemap["SOAP_ENC__unsignedByte"] = "typedef unsigned char SOAP_ENC__unsignedByte;"; - usetypemap["SOAP_ENC__unsignedByte"] = "SOAP_ENC__unsignedByte"; - deftypemap["SOAP_ENC__unsignedInt"] = "typedef unsigned int SOAP_ENC__unsignedInt;"; - usetypemap["SOAP_ENC__unsignedInt"] = "SOAP_ENC__unsignedInt"; - deftypemap["SOAP_ENC__unsignedLong"] = "typedef ULONG64 SOAP_ENC__unsignedLong;"; - usetypemap["SOAP_ENC__unsignedLong"] = "SOAP_ENC__unsignedLong"; - deftypemap["SOAP_ENC__unsignedShort"] = "typedef unsigned short SOAP_ENC__unsignedShort;"; - usetypemap["SOAP_ENC__unsignedShort"] = "SOAP_ENC__unsignedShort"; - deftypemap["SOAP_ENC__Array"] = ""; - usetypemap["SOAP_ENC__Array"] = "struct { _XML *__ptr; int __size; }"; - deftypemap["_SOAP_ENC__arrayType"] = ""; - deftypemap["SOAP_ENV__Header"] = ""; - usetypemap["SOAP_ENV__Header"] = "struct SOAP_ENV__Header"; - deftypemap["_SOAP_ENV__mustUnderstand"] = ""; - if (cflag || sflag) - usetypemap["_SOAP_ENV__mustUnderstand"] = "char*"; - else - usetypemap["_SOAP_ENV__mustUnderstand"] = "std::string"; - deftypemap["SOAP_ENV__Fault"] = ""; - usetypemap["SOAP_ENV__Fault"] = "struct SOAP_ENV__Fault"; - deftypemap["SOAP_ENV__detail"] = ""; - usetypemap["SOAP_ENV__detail"] = "struct SOAP_ENV__Detail"; - deftypemap["SOAP_ENV__Detail"] = ""; - usetypemap["SOAP_ENV__Detail"] = "struct SOAP_ENV__Detail"; - deftypemap["SOAP_ENV__Code"] = ""; - usetypemap["SOAP_ENV__Code"] = "struct SOAP_ENV__Code"; - deftypemap["SOAP_ENV__Reason"] = ""; - usetypemap["SOAP_ENV__Reason"] = "struct SOAP_ENV__Reason"; - if (read(mapfile)) - fprintf(stderr, "Problem reading type map file '%s'.\nUsing internal type definitions for %s instead.\n\n", mapfile, cflag?"C":"C++"); -} - -const char *Types::nsprefix(const char *prefix, const char *URI) -{ if (URI) - { const char *s = uris[URI]; - if (!s) - { size_t n; - if (!prefix || !*prefix || *prefix == '_') - s = schema_prefix; - else - s = estrdup(prefix); - if (!syms[s]) - n = syms[s] = 1; - else - n = ++syms[s]; - if (n != 1 || !prefix || !*prefix || *prefix == '_') - { char *t = (char*)emalloc(strlen(s) + 16); - sprintf(t, "%s%lu", s, (unsigned long)n); - s = t; - } - uris[URI] = s; - if (vflag) - fprintf(stderr, "namespace prefix %s = \"%s\"\n", s, URI); - } - // if *prefix == '_', then add prefix string to s - if (prefix && *prefix == '_') - { char *t = (char*)emalloc(strlen(s) + 2); - *t = '_'; - strcpy(t + 1, s); - s = t; - } - return s; - } - return NULL; -} - -const char *Types::prefix(const char *name) -{ const char *s; - char *t; - if (*name == '"') - { s = strchr(name + 1, '"'); - t = (char*)emalloc(s - name); - strncpy(t, name + 1, s - name - 1); - t[s - name - 1] = '\0'; - return nsprefix(NULL, t); - } - s = strchr(name, ':'); - if (s) - { t = (char*)emalloc(s - name + 1); - strncpy(t, name, s - name); - t[s - name] = '\0'; - return t; - } - return NULL; -} - -const char *Types::uri(const char *name) -{ const char *s; - char *t; - if (*name == '"') - { s = strchr(name + 1, '"'); - t = (char*)emalloc(s - name); - strncpy(t, name + 1, s - name - 1); - t[s - name - 1] = '\0'; - return t; - } - s = strchr(name, ':'); - if (s) - { struct Namespace *p = namespaces; - if (p) - { for (p += 6; p->id; p++) - { if (!strncmp(p->id, name, s - name) && !p->id[s - name]) - { if (p->in && *p->in) - return p->in; - return p->ns; - } - } - } - } - return NULL; -} - -// Find a C name for a QName. If the name has no qualifier, use URI. Suggest prefix for URI -const char *Types::fname(const char *prefix, const char *URI, const char *qname, SetOfString *reserved, enum Lookup lookup, bool isqname) -{ char buf[1024], *t; - const char *p, *s, *name; - if (!qname) - { fprintf(stream, "// Warning: internal error, no QName in fname()\n"); - if (vflag) - fprintf(stderr, "Internal error, no QName in fname()\n"); - qname = "?"; - } - name = qname; - if (isqname) - s = strrchr(name, ':'); - else - s = NULL; - if (s) - { name = s + 1; - if (qname[0] == '"' && qname[1] == '"') - s = NULL; - else if (*qname == '"') - { t = (char*)emalloc(s - qname - 1); - strncpy(t, qname + 1, s - qname - 2); - t[s - qname - 2] = '\0'; - URI = t; - } - else if (!strncmp(qname, "xs:", 3)) // this hack is necessary since the nsmap table defines "xs" for "xsd" - { s = "xsd"; - URI = NULL; - } - else - { t = (char*)emalloc(s - qname + 1); - strncpy(t, qname, s - qname); - t[s - qname] = '\0'; - s = t; - URI = NULL; - } - } - if (URI) - p = nsprefix(prefix, URI); - else if (s) - p = s; - else - p = ""; - s = NULL; - if (lookup == LOOKUP) - { if (qnames.find(Pair(p,name)) != qnames.end()) - s = qnames[Pair(p,name)]; - } - if (!s) - { t = buf; - if (!prefix || *prefix) - { s = p; - // no longer add '_' when URI != NULL, since nsprefix() will do this - if (prefix && *prefix == ':') - *t++ = ':'; - else if (prefix && *prefix == '_') - { if (!URI) - *t++ = '_'; - if (prefix[1] == '_') // ensures ns prefix starts with __ - { strcpy(t, prefix + 1); - t += strlen(prefix + 1); - } - } - if (s && *s) - { for (; *s; s++) - { if (isalnum(*s)) - *t++ = *s; - else if (*s == '-' && s[1] != '-' && s != p) - *t++ = '_'; - else if (*s == '_') - { if (s == p) - *t++ = '_'; - else if (!_flag) - { strcpy(t, "_USCORE"); - t += 7; - } - else - { s = utf8(t, s); - t += 6; - } - } - else - { s = utf8(t, s); - t += 6; - } - } - if (!prefix || *prefix != '*') - { *t++ = '_'; - *t++ = '_'; - } - } - else if (isdigit(*name)) - *t++ = '_'; - } - for (s = name; *s; s++) - { if (isalnum(*s)) - *t++ = *s; - else if (*s == '-' && s[1] != '-' && s[1] != '\0' && s != name) - *t++ = '_'; - else if (!_flag && *s == '_') - { strcpy(t, "_USCORE"); - t += 7; - } - else - { s = utf8(t, s); - t += 6; - } - if (t >= buf + sizeof(buf)) - break; - } - *t = '\0'; - while (knames.find(buf) != knames.end() || (reserved && reserved->find(buf) != reserved->end())) - { *t++ = '_'; - *t = '\0'; - } - if (isalpha(*buf) || *buf == '_' || *buf == ':') - { t = (char*)emalloc(strlen(buf) + 1); - strcpy(t, buf); - } - else - { t = (char*)emalloc(strlen(buf) + 2); - *t = '_'; - strcpy(t + 1, buf); - } - if (lookup == LOOKUP) - { qnames[Pair(p,name)] = t; - if (vflag) - { cerr << "Mapping '" << p << ":" << name << "' to '" << t << "'" << endl; -#ifdef DEBUG - for (MapOfPairToString::const_iterator i = qnames.begin(); i != qnames.end(); ++i) - cerr << "Map[" << (*i).first.first << ":" << (*i).first.second << "]='" << (*i).second << "'" << endl; -#endif - } - } - s = t; - } - if (eqvtypemap.find(s) != eqvtypemap.end()) - s = eqvtypemap[s]; - return s; -} - -bool Types::is_defined(const char *prefix, const char *URI, const char *qname) -{ const char *t = fname(prefix, URI, qname, NULL, LOOKUP, true); - return usetypemap.find(t) != usetypemap.end(); -} - -const char *Types::aname(const char *prefix, const char *URI, const char *qname) -{ return fname(prefix, URI, qname, NULL, NOLOOKUP, true); -} - -const char *Types::cname(const char *prefix, const char *URI, const char *qname) -{ return fname(prefix, URI, qname, NULL, LOOKUP, true); -} - -const char *Types::tname(const char *prefix, const char *URI, const char *qname) -{ const char *s, *t; - t = cname(prefix, URI, qname); - if (usetypemap.find(t) != usetypemap.end()) - { s = usetypemap[t]; - if (vflag) - cerr << "Mapping use of '" << t << "' to '" << s << "'" << endl; - } - else - { s = t; - fprintf(stream, "\n// Warning: undefined QName '%s' for type '%s' in namespace '%s' (FIXME: check WSDL and schema definitions)\n", qname?qname:"", t, URI?URI:"?"); - if (vflag) - fprintf(stderr, "\nWarning: undefined QName '%s' for type '%s' in namespace '%s'\n", qname?qname:"", t, URI?URI:"?"); - } - return s; -} - -const char *Types::tnameptr(bool flag, const char *prefix, const char *URI, const char *qname) -{ const char *s = pname(flag, prefix, URI, qname); - if (flag) - { if (!strncmp(s, "char*", 5)) - return "char**"; - if (!strchr(s, '*')) - { char *r = (char*)emalloc(strlen(s) + 2); - strcpy(r, s); - strcat(r, "*"); - return r; - } - } - return s; -} - -const char *Types::pname(bool flag, const char *prefix, const char *URI, const char *qname) -{ const char *r, *s = NULL, *t; - t = cname(prefix, URI, qname); - if (flag) - { if (ptrtypemap.find(t) != ptrtypemap.end()) - s = ptrtypemap[t]; - else - { if (usetypemap.find(t) != usetypemap.end()) - s = usetypemap[t]; - if (!s) - { s = t; - fprintf(stream, "\n// Warning: undefined QName '%s' for pointer to type '%s' (FIXME: check WSDL and schema definitions)\n", qname, t); - if (vflag) - fprintf(stderr, "\nWarning: undefined QName '%s' for pointer to type '%s' in namespace '%s'\n", qname, t, URI?URI:"?"); - } - r = s; - while (r && *r) - { r = strchr(r + 1, '*'); - if (r && *(r-1) != '/' && *(r+1) != '/') - break; - } - if (!r) // already pointer? - { char *p = (char*)emalloc(strlen(s) + 2); - strcpy(p, s); - strcat(p, "*"); - s = p; - } - if (vflag) - cerr << "Mapping pointer to '" << t << "' to '" << s << "'" << endl; - ptrtypemap[t] = s; - } - } - else if (usetypemap.find(t) != usetypemap.end()) - s = usetypemap[t]; - else - { s = t; - fprintf(stream, "\n// Warning: undefined QName '%s' for type '%s' in namespace '%s' (FIXME: check WSDL and schema definitions)\n", qname, t, URI?URI:"?"); - if (vflag) - fprintf(stderr, "\nWarning: undefined QName '%s' for type '%s' in namespace '%s'\n", qname, t, URI?URI:"?"); - } - return s; -} - -const char *Types::deftname(enum Type type, const char *pointer, bool is_pointer, const char *prefix, const char *URI, const char *qname) -{ char buf[1024]; - char *s; - const char *q = NULL, *t; - t = fname(prefix, URI, qname, NULL, LOOKUP, true); - if (deftypemap[t]) - { if (vflag) - fprintf(stderr, "Name %s already defined (probably in %s file)\n", qname, mapfile); - return NULL; - } - if (usetypemap[t]) - { if (vflag) - fprintf(stderr, "Name %s is mapped\n", qname); - return t; - } - switch (type) - { case ENUM: - q = "enum"; - if (yflag) - knames.insert(t); - break; - case STRUCT: - q = "struct"; - if (yflag) - knames.insert(t); - break; - case CLASS: - case TYPEDEF: - knames.insert(t); - default: - break; - } - if (q) - { strcpy(buf, q); - strcat(buf, " "); - } - else - buf[0] = '\0'; - strcat(buf, t); - if (pointer) - strcat(buf, pointer); - s = (char*)emalloc(strlen(buf) + 1); - strcpy(s, buf); - usetypemap[t] = s; - if (pointer || is_pointer) - ptrtypemap[t] = s; - if (vflag) - cerr << "Defined '" << t << "' ('" << qname << "' in namespace '" << (URI?URI:prefix?prefix:"") << "') as '" << s << endl; - return t; -} - -// get enumeration value. URI/type refers to the enum simpleType. -const char *Types::ename(const char *type, const char *value, bool isqname) -{ const char *s = enames[Pair(type,value)]; - if (!s) - { s = fname(NULL, NULL, value, &rnames, NOLOOKUP, isqname); - if (!eflag && type && *type) - { // Add prefix to enum - if (!*s || (s[0] == '_' && s[1] == '\0')) - s = "_x0000"; - char *buf = (char*)emalloc(strlen(type) + strlen(s) + 3); - // _xXXXX is OK here - if (s[0] == '_' && s[1] != 'x' && strncmp(s, "_USCORE", 7)) - sprintf(buf, "%s_%s", type, s); - else - sprintf(buf, "%s__%s", type, s); - s = buf; - } - else - rnames.insert(s); - enames[Pair(type,value)] = s; - } - return s; -} - -// get operation name -const char *Types::oname(const char *prefix, const char *URI, const char *qname) -{ const char *s = fname(prefix, URI, qname, NULL, LOOKUP, true); - if (s && usetypemap.find(s) != usetypemap.end()) - { // Avoid name clash with structs/classes of the same name - onames.insert(s); - } - s = fname(prefix, URI, qname, &onames, NOLOOKUP, true); - onames.insert(s); - return s; -} - -// generate struct name -const char *Types::sname(const char *URI, const char *name) -{ const char *s; - char *t; - if (!aflag && name) - { size_t len = 0; - for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i) - len += strlen(*i) + 1; - t = (char*)emalloc(len + strlen(name) + 1); - *t = '\0'; - for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j) - { strcat(t, *j); - strcat(t, "-"); - } - strcat(t, name); - s = fname("_", URI, t, &rnames, NOLOOKUP, true); - rnames.insert(s); - } - else if (URI) - { s = nsprefix(NULL, URI); - t = (char*)emalloc(strlen(s) + 16); - sprintf(t, "_%s__struct_%d", s, snum++); - s = t; - } - else - { t = (char*)emalloc(16); - sprintf(t, "struct_%d", snum++); - s = t; - } - return s; -} - -// generate union name -const char *Types::uname(const char *URI) -{ const char *s; - char *t; - if (!aflag) - { size_t len = 0; - for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i) - len += strlen(*i) + 1; - t = (char*)emalloc(len + 6); - strcpy(t, "union"); - for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j) - { strcat(t, "-"); - strcat(t, *j); - } - s = fname("_", URI, t, &rnames, NOLOOKUP, true); - rnames.insert(s); - } - else if (URI) - { s = nsprefix(NULL, URI); - t = (char*)emalloc(strlen(s) + 16); - sprintf(t, "_%s__union_%d", s, unum++); - s = t; - } - else - { t = (char*)emalloc(16); - sprintf(t, "_union_%d", unum++); - s = t; - } - return s; -} - -// generate enum name -const char *Types::gname(const char *URI, const char *name) -{ const char *s; - char *t; - if (!aflag && name) - { size_t len = 0; - for (VectorOfString::const_iterator i = scope.begin(); i != scope.end(); ++i) - len += strlen(*i) + 1; - t = (char*)emalloc(len + strlen(name) + 1); - *t = '\0'; - for (VectorOfString::const_iterator j = scope.begin(); j != scope.end(); ++j) - { strcat(t, *j); - strcat(t, "-"); - } - strcat(t, name); - s = fname("_", URI, t, &rnames, LOOKUP, true); - rnames.insert(s); - } - else if (URI) - { s = nsprefix(NULL, URI); - t = (char*)emalloc(strlen(s) + 16); - sprintf(t, "_%s__enum_%d", s, gnum++); - s = t; - } - else - { t = (char*)emalloc(16); - sprintf(t, "enum_%d", gnum++); - s = t; - } - return s; -} - -// checks if nillable or minOccurs=0 (and no default value is present) -bool Types::is_nillable(const xs__element& element) -{ return !element.default_ && (element.nillable || (element.minOccurs && !strcmp(element.minOccurs, "0"))); -} - -bool Types::is_basetypeforunion(const char *prefix, const char *URI, const char *type) -{ const char *t = tname(prefix, URI, type); - if (!strcmp(t, "std::string") || !strcmp(t, "std::wstring")) - return false; - return is_basetype(prefix, URI, type); -} - -bool Types::is_basetype(const char *prefix, const char *URI, const char *type) -{ const char *t = tname(prefix, URI, type); - if (!strncmp(t, "enum ", 5)) - return true; - if (strstr(t, "__") && strcmp(t, "xsd__byte")) - return false; - return !strncmp(type, "xs:", 3) || !strncmp(type, "SOAP-ENC:", 9); -} - -void Types::dump(FILE *fd) -{ fprintf(fd, "\nTypes:\n"); - for (MapOfStringToString::const_iterator i = usetypemap.begin(); i != usetypemap.end(); ++i) - fprintf(fd, "%s=%s\n", (*i).first, (*i).second?(*i).second:"(null)"); - fprintf(fd, "\nPointers:\n"); - for (MapOfStringToString::const_iterator j = ptrtypemap.begin(); j != ptrtypemap.end(); ++j) - fprintf(fd, "%s=%s\n", (*j).first, (*j).second?(*j).second:"(null)"); -} - -void Types::define(const char *URI, const char *name, const xs__complexType& complexType) -{ // generate prototype for structs/classes and store name - const char *prefix = NULL; - if (complexType.name) - name = complexType.name; - else - prefix = "_"; - if (complexType.complexContent - && complexType.complexContent->restriction - && !strcmp(complexType.complexContent->restriction->base, "SOAP-ENC:Array")) - { if (strcmp(schema_prefix, "ns")) - prefix = "*"; - else - prefix = ""; - } - if (cflag) - { const char *t = deftname(STRUCT, "*", true, prefix, URI, name); - if (t) - { if (yflag) - fprintf(stream, "\n/// Typedef synonym for struct %s.\ntypedef struct %s %s;\n", t, t, t); - } - else if (name) - { t = deftypemap[cname(prefix, URI, name)]; - if (t) - { fprintf(stream, "\n/// Imported complexType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:""); - document(complexType.annotation); - if (*t) - format(t); - else - fprintf(stream, "// complexType definition intentionally left blank.\n"); - } - } - } - else - { const char *t = deftname(CLASS, "*", true, prefix, URI, name); - if (t) - fprintf(stream, "\n// Forward declaration of class %s.\nclass %s;\n", t, t); - else if (name) - { t = deftypemap[cname(prefix, URI, name)]; - if (t) - { fprintf(stream, "\n/// Imported complexType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:""); - document(complexType.annotation); - if (*t) - format(t); - else - fprintf(stream, "// complexType definition intentionally left blank.\n"); - } - } - } -} - -void Types::gen(const char *URI, const char *name, const xs__simpleType& simpleType, bool anonymous) -{ const char *t = NULL; - const char *prefix = NULL; - if (simpleType.name) - name = simpleType.name; - else - prefix = "_"; - if (!anonymous) - { t = deftypemap[cname(NULL, URI, name)]; - if (t) - { fprintf(stream, "\n/// Imported simpleType \"%s\":%s from typemap %s.\n", URI, name, mapfile?mapfile:""); - document(simpleType.annotation); - if (*t) - format(t); - else - fprintf(stream, "// simpleType definition intentionally left blank.\n"); - return; - } - } - if (simpleType.restriction) - { const char *base = simpleType.restriction->base; - if (!base && simpleType.restriction->simpleType) - { if (!anonymous) - { if (simpleType.restriction->simpleType->list && simpleType.restriction->length && simpleType.restriction->length->value) - { fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction list with length %s.", URI?URI:"", name, simpleType.restriction->length->value); - document(simpleType.restriction->length->annotation); - } - else - fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction.", URI?URI:"", name); - } - gen(URI, name, *simpleType.restriction->simpleType, anonymous); - } - else - { if (!base) - base = "xsd:string"; - const char *baseURI = NULL; - if (simpleType.restriction->simpleTypePtr() && simpleType.restriction->simpleTypePtr()->schemaPtr()) - baseURI = simpleType.restriction->simpleTypePtr()->schemaPtr()->targetNamespace; - if (!anonymous) - fprintf(stream, "\n/// \"%s\":%s is a simpleType restriction of %s.\n", URI?URI:"", name, base); - document(simpleType.annotation); - document(simpleType.restriction->annotation); - if (!simpleType.restriction->enumeration.empty()) - { bool is_numeric = true; // check if all enumeration values are numeric - bool is_qname = !strcmp(base, "xs:QName"); - if (!anonymous) - { t = deftname(ENUM, NULL, false, prefix, URI, name); - if (t && !eflag) - fprintf(stream, "/// Note: enum values are prefixed with '%s' to avoid name clashes, please use wsdl2h option -e to omit this prefix\n", t); - } - if (!t) - t = gname(URI, name); - if (!anonymous) - fprintf(stream, "enum %s\n{\n", t); - else - fprintf(stream, " enum %s\n {\n", t); - for (vector<xs__enumeration>::const_iterator enumeration1 = simpleType.restriction->enumeration.begin(); enumeration1 != simpleType.restriction->enumeration.end(); ++enumeration1) - { const char *s; - if ((s = (*enumeration1).value)) - is_numeric &= is_integer(s); - } - SetOfString enumvals; - for (vector<xs__enumeration>::const_iterator enumeration2 = simpleType.restriction->enumeration.begin(); enumeration2 != simpleType.restriction->enumeration.end(); ++enumeration2) - { const char *s; - document((*enumeration2).annotation); - if ((s = (*enumeration2).value)) - { if (!enumvals.count(s)) - { enumvals.insert(s); - if (is_numeric) - fprintf(stream, "\t%s = %s,\t///< %s value=\"%s\"\n", ename(t, s, false), s, base, s); - else if (is_qname && (*enumeration2).value_) - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration2).value_, true), base, (*enumeration2).value_); - else - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, s, false), base, s); - } - } - else - fprintf(stream, "//\tunrecognized: enumeration '%s' has no value\n", name?name:""); - } - if (!anonymous) - { fprintf(stream, "};\n"); - if (yflag) - fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t); - if (pflag && simpleType.name) - { const char *s = aname(prefix, URI, name); - knames.insert(s); - s = aname(prefix, URI, name); - fprintf(stream, "\n/// Class wrapper\n"); - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s); - fprintf(stream, elementformat, tname(prefix, URI, name), "__item;"); - modify(s); - fprintf(stream, "\n};\n"); - } - } - else - fprintf(stream, " }\n"); - } - else - { if (simpleType.restriction->length && simpleType.restriction->length->value) - { fprintf(stream, "/// Length of this string is exactly %s characters\n", simpleType.restriction->length->value); - document(simpleType.restriction->length->annotation); - } - else - { const char *a = NULL, *b = NULL; - if (simpleType.restriction->minLength) - { a = simpleType.restriction->minLength->value; - document(simpleType.restriction->minLength->annotation); - } - if (simpleType.restriction->maxLength) - { b = simpleType.restriction->maxLength->value; - document(simpleType.restriction->maxLength->annotation); - } - if (a || b) - fprintf(stream, "/// Length of this string is within %s..%s characters\n", a?a:"0", b?b:""); - } - if (simpleType.restriction->precision && simpleType.restriction->precision->value) - fprintf(stream, "/// %sprecision is %s (note: not automatically enforced)\n", simpleType.restriction->precision->fixed?"fixed ":"", simpleType.restriction->precision->value); - if (simpleType.restriction->scale && simpleType.restriction->scale->value) - fprintf(stream, "/// %sscale is %s (note: not automatically enforced)\n", simpleType.restriction->scale->fixed?"fixed ":"", simpleType.restriction->scale->value); - if (simpleType.restriction->totalDigits && simpleType.restriction->totalDigits->value) - fprintf(stream, "/// %snumber of total digits is %s (note: not automatically enforced)\n", simpleType.restriction->totalDigits->fixed?"fixed ":"", simpleType.restriction->totalDigits->value); - if (simpleType.restriction->fractionDigits && simpleType.restriction->fractionDigits->value) - fprintf(stream, "/// %snumber of fraction digits is %s (note: not automatically enforced)\n", simpleType.restriction->fractionDigits->fixed?"fixed ":"", simpleType.restriction->fractionDigits->value); - for (vector<xs__pattern>::const_iterator pattern1 = simpleType.restriction->pattern.begin(); pattern1 != simpleType.restriction->pattern.end(); ++pattern1) - fprintf(stream, "/// Content pattern is \"%s\" (note: not automatically enforced)\n", xstring((*pattern1).value)); - const char *ai = NULL, *ae = NULL, *bi = NULL, *be = NULL; - if (simpleType.restriction->minInclusive) - { ai = simpleType.restriction->minInclusive->value; - document(simpleType.restriction->minInclusive->annotation); - } - else if (simpleType.restriction->minExclusive) - { ae = simpleType.restriction->minExclusive->value; - document(simpleType.restriction->minExclusive->annotation); - } - if (simpleType.restriction->maxInclusive) - { bi = simpleType.restriction->maxInclusive->value; - document(simpleType.restriction->maxInclusive->annotation); - } - else if (simpleType.restriction->maxExclusive) - { be = simpleType.restriction->maxExclusive->value; - document(simpleType.restriction->maxExclusive->annotation); - } - if (ai || ae || bi || be) - { fprintf(stream, "/// Value range is "); - if (ai) - fprintf(stream, "[%s..", ai); - else if (ae) - fprintf(stream, "(%s..", ae); - else - fprintf(stream, "[.."); - if (bi) - fprintf(stream, "%s]\n", bi); - else if (be) - fprintf(stream, "%s)\n", be); - else - fprintf(stream, "]\n"); - } - if (!simpleType.restriction->attribute.empty()) - { if (!Wflag) - fprintf(stderr, "\nWarning: simpleType '%s' should not have attributes\n", name?name:""); - } - const char *s = tname(NULL, baseURI, base); - if (!anonymous) - { bool is_ptr = false; - is_ptr = (strchr(s, '*') != NULL) || (s == pname(true, NULL, baseURI, base)); - t = deftname(TYPEDEF, NULL, is_ptr, prefix, URI, name); - if (t) - fprintf(stream, "typedef %s %s", s, t); - } - else - { t = ""; - fprintf(stream, elementformat, s, ""); - fprintf(stream, "\n"); - } - if (t) - { if (!anonymous && !simpleType.restriction->pattern.empty()) - { fprintf(stream, " \""); - for (vector<xs__pattern>::const_iterator pattern2 = simpleType.restriction->pattern.begin(); pattern2 != simpleType.restriction->pattern.end(); ++pattern2) - { if (pattern2 != simpleType.restriction->pattern.begin()) - fprintf(stream, "|"); - fprintf(stream, "%s", xstring((*pattern2).value)); - } - fprintf(stream, "\""); - } - // add range info only when type is numeric - bool is_numeric = false, is_float = false; - if (!strncmp(s, "unsigned ", 9)) - s += 9; - else if (!strncmp(s, "xsd__unsigned", 13)) - s += 13; - else if (!strncmp(s, "xsd__", 5)) - s += 5; - if (!strcmp(s, "double") - || !strcmp(s, "float")) - is_numeric = is_float = true; - else if (!strcmp(s, "bool") - || !strcmp(s, "byte") - || !strcmp(s, "Byte") - || !strcmp(s, "char") - || !strcmp(s, "double") - || !strcmp(s, "float") - || !strcmp(s, "int") - || !strcmp(s, "Int") - || !strcmp(s, "long") - || !strcmp(s, "Long") - || !strcmp(s, "LONG64") - || !strcmp(s, "short") - || !strcmp(s, "Short") - || !strcmp(s, "ULONG64")) - is_numeric = true; - if (!anonymous - && simpleType.restriction->minLength - && simpleType.restriction->minLength->value) - fprintf(stream, " %s", simpleType.restriction->minLength->value); - else if (is_numeric - && !anonymous - && simpleType.restriction->minInclusive - && simpleType.restriction->minInclusive->value - && is_integer(simpleType.restriction->minInclusive->value)) - fprintf(stream, " %s", simpleType.restriction->minInclusive->value); - else if (is_float - && !anonymous - && simpleType.restriction->minExclusive - && simpleType.restriction->minExclusive->value - && is_integer(simpleType.restriction->minExclusive->value)) - fprintf(stream, " %s", simpleType.restriction->minExclusive->value); - else if (is_numeric - && !anonymous - && simpleType.restriction->minExclusive - && simpleType.restriction->minExclusive->value - && is_integer(simpleType.restriction->minExclusive->value)) - fprintf(stream, " " SOAP_LONG_FORMAT, to_integer(simpleType.restriction->minExclusive->value)+1); - if (!anonymous - && simpleType.restriction->maxLength - && simpleType.restriction->maxLength->value) - fprintf(stream, ":%s", simpleType.restriction->maxLength->value); - else if (is_numeric - && !anonymous - && simpleType.restriction->maxInclusive - && simpleType.restriction->maxInclusive->value - && is_integer(simpleType.restriction->maxInclusive->value)) - fprintf(stream, ":%s", simpleType.restriction->maxInclusive->value); - else if (is_float - && !anonymous - && simpleType.restriction->maxExclusive - && simpleType.restriction->maxExclusive->value - && is_integer(simpleType.restriction->maxExclusive->value)) - fprintf(stream, ":%s", simpleType.restriction->maxExclusive->value); - else if (is_numeric - && !anonymous - && simpleType.restriction->maxExclusive - && simpleType.restriction->maxExclusive->value - && is_integer(simpleType.restriction->maxExclusive->value)) - fprintf(stream, ":" SOAP_LONG_FORMAT, to_integer(simpleType.restriction->maxExclusive->value)-1); - if (!anonymous) - { fprintf(stream, ";\n"); - if (pflag && simpleType.name) - { const char *s = aname(prefix, URI, name); - knames.insert(s); - s = aname(prefix, URI, name); - fprintf(stream, "\n/// Class wrapper\n"); - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s); - fprintf(stream, elementformat, tname(prefix, URI, name), "__item;"); - modify(s); - fprintf(stream, "\n};\n"); - } - } - } - } - } - } - else if (simpleType.list) - { if (simpleType.list->restriction && simpleType.list->restriction->base) - { if (!anonymous) - { fprintf(stream, "\n/// \"%s\":%s is a simpleType list restriction of %s.\n", URI?URI:"", name, simpleType.list->restriction->base); - fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n"); - } - document(simpleType.annotation); - if (!anonymous) - { t = deftname(ENUM, NULL, false, prefix, URI, name); - if (t) - fprintf(stream, "enum * %s\n{\n", t); - } - else - { t = ""; - fprintf(stream, "enum *\n{\n"); - } - if (t) - { for (vector<xs__enumeration>::const_iterator enumeration = simpleType.list->restriction->enumeration.begin(); enumeration != simpleType.list->restriction->enumeration.end(); ++enumeration) - { if ((*enumeration).value) - { if (!strcmp(simpleType.list->restriction->base, "xs:QName") && (*enumeration).value_) - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), simpleType.list->restriction->base, (*enumeration).value_); - else - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), simpleType.list->restriction->base, (*enumeration).value); - } - else - fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t); - } - if (!anonymous) - { fprintf(stream, "};\n"); - if (yflag) - fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t); - if (pflag && simpleType.name) - { const char *s = aname(prefix, URI, name); - knames.insert(s); - s = aname(prefix, URI, name); - fprintf(stream, "\n/// Class wrapper\n"); - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s); - fprintf(stream, elementformat, tname(prefix, URI, name), "__item;"); - modify(s); - fprintf(stream, "\n};\n"); - } - } - else - fprintf(stream, "}\n"); - } - } - else if (simpleType.list->itemType) - { const xs__simpleType *p = simpleType.list->itemTypePtr(); - if (p - && p->restriction - && p->restriction->base - && !p->restriction->enumeration.empty() - && p->restriction->enumeration.size() <= 64) - { if (!anonymous) - { fprintf(stream, "\n/// \"%s\":%s is a simpleType list of %s.\n", URI?URI:"", name, simpleType.list->itemType); - fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n"); - } - document(simpleType.annotation); - if (!anonymous) - { t = deftname(ENUM, NULL, false, prefix, URI, name); - if (t) - fprintf(stream, "enum * %s\n{\n", t); - } - else - { t = ""; - fprintf(stream, "enum *\n{\n"); - } - if (t) - { for (vector<xs__enumeration>::const_iterator enumeration = p->restriction->enumeration.begin(); enumeration != p->restriction->enumeration.end(); ++enumeration) - { if ((*enumeration).value) - { if (!strcmp(p->restriction->base, "xs:QName") && (*enumeration).value_) - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), p->restriction->base, (*enumeration).value_); - else - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), p->restriction->base, (*enumeration).value); - } - else - fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t); - } - if (!anonymous) - { fprintf(stream, "};\n"); - if (yflag) - fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t); - if (pflag && simpleType.name) - { const char *s = aname(prefix, URI, name); - knames.insert(s); - s = aname(prefix, URI, name); - fprintf(stream, "\n/// Class wrapper.\n"); - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s); - fprintf(stream, elementformat, tname(prefix, URI, name), "__item;"); - modify(s); - fprintf(stream, "\n};\n"); - } - } - else - fprintf(stream, "}\n"); - } - } - else - { const char *s; - if (!strcmp(simpleType.list->itemType, "xs:QName")) - s = tname(NULL, NULL, "xsd:QName"); - else - s = tname(NULL, NULL, "xsd:string"); - if (!anonymous) - { fprintf(stream, "\n/// \"%s\":%s is a simpleType containing a whitespace separated list of %s.\n", URI?URI:"", name, simpleType.list->itemType); - t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name); - } - document(simpleType.annotation); - if (t) - fprintf(stream, "typedef %s %s;\n", s, t); - else - { fprintf(stream, elementformat, s, ""); - fprintf(stream, "\n"); - } - } - } - else - { if (!anonymous) - { fprintf(stream, "\n/// \"%s\":%s is a simpleType list.\n", URI?URI:"", name); - fprintf(stream, "/// Note: this enumeration is a bitmask, so a set of values is supported (using | and & bit-ops on the bit vector).\n"); - } - document(simpleType.annotation); - if (!anonymous) - { t = deftname(ENUM, NULL, false, prefix, URI, name); - if (t && !eflag) - fprintf(stream, "/// Note: enum values are prefixed with '%s' to avoid name clashes, please use wsdl2h option -e to omit this prefix\n", t); - } - else - t = ""; - if (t) - { fprintf(stream, "enum * %s\n{\n", t); - for (vector<xs__simpleType>::const_iterator simple = simpleType.list->simpleType.begin(); simple != simpleType.list->simpleType.end(); ++simple) - { if ((*simple).restriction && (*simple).restriction->base) - { for (vector<xs__enumeration>::const_iterator enumeration = (*simple).restriction->enumeration.begin(); enumeration != (*simple).restriction->enumeration.end(); ++enumeration) - { if ((*enumeration).value) - { if (!strcmp((*simple).restriction->base, "xs:QName") && (*enumeration).value_) - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value_, true), (*simple).restriction->base, (*enumeration).value_); - else - fprintf(stream, "\t%s,\t///< %s value=\"%s\"\n", ename(t, (*enumeration).value, false), (*simple).restriction->base, (*enumeration).value); - } - else - fprintf(stream, "//\tunrecognized: bitmask enumeration '%s' has no value\n", t); - } - } - } - if (!anonymous) - { fprintf(stream, "};\n"); - if (yflag) - fprintf(stream, "/// Typedef synonym for enum %s.\ntypedef enum %s %s;\n", t, t, t); - if (pflag && simpleType.name) - { const char *s = aname(prefix, URI, name); - knames.insert(s); - s = aname(prefix, URI, name); - fprintf(stream, "\n/// Class wrapper.\n"); - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", s); - fprintf(stream, elementformat, tname(prefix, URI, name), "__item;"); - modify(s); - fprintf(stream, "\n};\n"); - } - } - else - fprintf(stream, "}\n"); - } - } - } - else if (simpleType.union_) - { if (simpleType.union_->memberTypes) - { const char *s = tname(NULL, NULL, "xsd:string"); - if (!anonymous) - t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name); - fprintf(stream, "\n/// union of values \"%s\"\n", simpleType.union_->memberTypes); - if (t) - fprintf(stream, "typedef %s %s;\n", s, t); - else - { fprintf(stream, elementformat, s, ""); - fprintf(stream, "\n"); - } - } - else if (!simpleType.union_->simpleType.empty()) - { const char *s = tname(NULL, NULL, "xsd:string"); - fprintf(stream, "\n"); - if (!anonymous) - t = deftname(TYPEDEF, NULL, strchr(s, '*') != NULL, prefix, URI, name); - for (vector<xs__simpleType>::const_iterator simpleType1 = simpleType.union_->simpleType.begin(); simpleType1 != simpleType.union_->simpleType.end(); ++simpleType1) - if ((*simpleType1).restriction) - { fprintf(stream, "/// union of values from \"%s\"\n", (*simpleType1).restriction->base); - // TODO: are there any other types we should report here? - } - if (t) - fprintf(stream, "typedef %s %s;\n", s, t); - else - { fprintf(stream, elementformat, s, ""); - fprintf(stream, "\n"); - } - } - else - fprintf(stream, "//\tunrecognized\n"); - } - else - fprintf(stream, "//\tunrecognized simpleType\n"); -} - -void Types::gen(const char *URI, const char *name, const xs__complexType& complexType, bool anonymous) -{ const char *t = NULL; - const char *prefix = NULL; - bool soapflag = false; - if (complexType.name) - name = complexType.name; - else - prefix = "_"; - if (anonymous && name) - t = sname(URI, name); - else if (name) - { t = cname(prefix, URI, name); - if (deftypemap[t]) - return; - } - if (name) - scope.push_back(name); - if (complexType.simpleContent) - { if (!anonymous) - fprintf(stream, "\n/// \"%s\":%s is a%s complexType with simpleContent.\n", URI?URI:"", name, complexType.abstract?"n abstract":""); - document(complexType.annotation); - operations(t); - if (complexType.simpleContent->restriction) - { if (anonymous) - { if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (pflag && complexType.name) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - const char *base = "xs:string"; - const char *baseURI = NULL; - const xs__complexType *p = &complexType; - do - { if (!p->simpleContent) - break; - if (p->simpleContent->restriction) - { if (p->simpleContent->restriction->complexTypePtr()) - p = p->simpleContent->restriction->complexTypePtr(); - else - { base = p->simpleContent->restriction->base; - if (p->simpleContent->restriction->simpleTypePtr() && p->simpleContent->restriction->simpleTypePtr()->schemaPtr()) - baseURI = p->simpleContent->restriction->simpleTypePtr()->schemaPtr()->targetNamespace; - break; - } - } - else if (p->simpleContent->extension) - { if (p->simpleContent->extension->complexTypePtr()) - p = p->simpleContent->extension->complexTypePtr(); - else - { base = p->simpleContent->extension->base; - if (p->simpleContent->extension->simpleTypePtr() && p->simpleContent->extension->simpleTypePtr()->schemaPtr()) - baseURI = p->simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace; - break; - } - } - else - break; - } - while (p); - fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base); - fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item"); - fprintf(stream, ";\n"); - p = &complexType; - bool flag = true; - do - { if (!p->simpleContent) - break; - if (p->simpleContent->restriction) - { // TODO: should only generate attribute when name is different? - gen(URI, p->simpleContent->restriction->attribute); - if (p->simpleContent->restriction->anyAttribute && flag) - { gen(URI, *p->simpleContent->restriction->anyAttribute); - flag = false; - } - if (p->simpleContent->restriction->complexTypePtr()) - p = p->simpleContent->restriction->complexTypePtr(); - else - break; - } - else if (p->simpleContent->extension) - { gen(URI, p->simpleContent->extension->attribute); - gen(URI, p->simpleContent->extension->attributeGroup); - if (p->simpleContent->extension->anyAttribute && flag) - { gen(URI, *p->simpleContent->extension->anyAttribute); - flag = false; - } - if (p->simpleContent->extension->complexTypePtr()) - p = p->simpleContent->extension->complexTypePtr(); - else - break; - } - else - break; - } - while (p); - } - else if (complexType.simpleContent->extension) - { const char *base = "xs:string"; - const char *baseURI = NULL; - if (cflag || fflag || anonymous) - { if (anonymous) - { if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (pflag && complexType.name) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - const xs__complexType *p = &complexType; - do - { if (!p->simpleContent) - break; - if (p->simpleContent->restriction) - { if (p->simpleContent->restriction->complexTypePtr()) - p = p->simpleContent->restriction->complexTypePtr(); - else - { base = p->simpleContent->restriction->base; - if (p->simpleContent->restriction->simpleTypePtr() && p->simpleContent->restriction->simpleTypePtr()->schemaPtr()) - baseURI = p->simpleContent->restriction->simpleTypePtr()->schemaPtr()->targetNamespace; - break; - } - } - else if (p->simpleContent->extension) - { if (p->simpleContent->extension->complexTypePtr()) - p = p->simpleContent->extension->complexTypePtr(); - else - { base = p->simpleContent->extension->base; - if (p->simpleContent->extension->simpleTypePtr() && p->simpleContent->extension->simpleTypePtr()->schemaPtr()) - baseURI = p->simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace; - break; - } - } - else - break; - } - while (p); - fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base); - fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item"); - fprintf(stream, ";\n"); - p = &complexType; - bool flag = true; - do - { if (!p->simpleContent) - break; - if (p->simpleContent->restriction) - { gen(URI, p->simpleContent->restriction->attribute); - if (p->simpleContent->restriction->anyAttribute && flag) - gen(URI, *p->simpleContent->restriction->anyAttribute); - break; - } - else if (p->simpleContent->extension) - { gen(URI, p->simpleContent->extension->attribute); - gen(URI, p->simpleContent->extension->attributeGroup); - if (p->simpleContent->extension->anyAttribute && flag) - { gen(URI, *p->simpleContent->extension->anyAttribute); - flag = false; - } - if (p->simpleContent->extension->complexTypePtr()) - p = p->simpleContent->extension->complexTypePtr(); - else - break; - } - else - break; - } - while (p); - } - else - { base = complexType.simpleContent->extension->base; - if ( - /* TODO: in future, may want to add check here for base type == class - complexType.simpleContent->extension->simpleTypePtr() - || - */ - complexType.simpleContent->extension->complexTypePtr()) - { if (complexType.simpleContent->extension->complexTypePtr()->schemaPtr()) - baseURI = complexType.simpleContent->extension->complexTypePtr()->schemaPtr()->targetNamespace; - fprintf(stream, "class %s : public %s\n{ public:\n", t, cname(NULL, baseURI, base)); - soapflag = true; - } - else - { if (complexType.simpleContent->extension->simpleTypePtr() && complexType.simpleContent->extension->simpleTypePtr()->schemaPtr()) - baseURI = complexType.simpleContent->extension->simpleTypePtr()->schemaPtr()->targetNamespace; - else if (complexType.simpleContent->extension->complexTypePtr() && complexType.simpleContent->extension->complexTypePtr()->schemaPtr()) - baseURI = complexType.simpleContent->extension->complexTypePtr()->schemaPtr()->targetNamespace; - if (pflag && complexType.name) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - fprintf(stream, "/// __item wraps '%s' simpleContent.\n", base); - fprintf(stream, elementformat, tname(NULL, baseURI, base), "__item"); - fprintf(stream, ";\n"); - } - gen(URI, complexType.simpleContent->extension->attribute); - gen(URI, complexType.simpleContent->extension->attributeGroup); - if (complexType.simpleContent->extension->anyAttribute) - gen(URI, *complexType.simpleContent->extension->anyAttribute); - } - } - else - fprintf(stream, "//\tunrecognized\n"); - } - else if (complexType.complexContent) - { if (complexType.complexContent->restriction) - { if (!anonymous) - 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); - document(complexType.annotation); - operations(t); - if (!strcmp(complexType.complexContent->restriction->base, "SOAP-ENC:Array")) - { char *item = NULL, *type = NULL; - if (!complexType.complexContent->restriction->attribute.empty()) - { xs__attribute& attribute = complexType.complexContent->restriction->attribute.front(); - if (attribute.wsdl__arrayType) - type = attribute.wsdl__arrayType; - } - xs__seqchoice *s = complexType.complexContent->restriction->sequence; - if (s - && !s->__contents.empty() - && s->__contents.front().__union == SOAP_UNION_xs__union_content_element - && s->__contents.front().__content.element) - { xs__element& element = *s->__contents.front().__content.element; - if (!type) - { if (element.type) - type = element.type; - else if (element.simpleTypePtr()) - { if (element.simpleTypePtr()->name) - type = element.simpleTypePtr()->name; - else if (element.simpleTypePtr()->restriction) - type = element.simpleTypePtr()->restriction->base; - } - else if (element.complexTypePtr()) - { if (element.complexTypePtr()->name) - type = element.complexTypePtr()->name; - else if (element.complexTypePtr()->complexContent && element.complexTypePtr()->complexContent->restriction) - type = element.complexTypePtr()->complexContent->restriction->base; - } - } - item = element.name; // <sequence><element name="item" type="..."/></sequence> - } - gen_soap_array(name, t, item, type); - } - else - { if (anonymous) - { if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (pflag && complexType.name) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - if (complexType.complexContent->restriction->group) - gen(URI, *complexType.complexContent->restriction->group, NULL, NULL); - if (complexType.complexContent->restriction->all) - gen(URI, *complexType.complexContent->restriction->all, NULL, NULL); - if (complexType.complexContent->restriction->sequence) - gen(URI, *complexType.complexContent->restriction->sequence, NULL, NULL); - if (complexType.complexContent->restriction->choice) - gen(URI, name, *complexType.complexContent->restriction->choice, NULL, NULL); - gen(URI, complexType.complexContent->restriction->attribute); - bool flag = true; - if (complexType.complexContent->restriction->anyAttribute) - { gen(URI, *complexType.complexContent->restriction->anyAttribute); - flag = false; - } - const xs__complexType *p = complexType.complexContent->restriction->complexTypePtr(); - while (p) - { const char *pURI; - if (p->schemaPtr()) - pURI = p->schemaPtr()->targetNamespace; - else - pURI = URI; - const char *b = cname(NULL, pURI, p->name); - if (zflag && zflag <= 5) - fprintf(stream, "/// RESTRICTED FROM %s:\n", b); - else if (comment_nest == 0) - fprintf(stream, "/* RESTRICTED FROM %s:\n", b); - else - fprintf(stream, " RESTRICTED FROM %s:\n", b); - comment_nest++; - if (p->complexContent && p->complexContent->restriction) - { gen(URI, p->complexContent->restriction->attribute); - if (p->complexContent->restriction->anyAttribute && flag) - { gen(URI, *p->complexContent->restriction->anyAttribute); - flag = false; - } - p = p->complexContent->restriction->complexTypePtr(); - } - else if (p->complexContent && p->complexContent->extension) - { gen(URI, p->complexContent->extension->attribute); - gen(URI, p->complexContent->extension->attributeGroup); - if (p->complexContent->extension->anyAttribute && flag) - { gen(URI, *p->complexContent->extension->anyAttribute); - flag = false; - } - p = p->complexContent->extension->complexTypePtr(); - } - else - { gen(URI, p->attribute); - gen(URI, p->attributeGroup); - if (p->anyAttribute && flag) - gen(URI, *p->anyAttribute); - p = NULL; - } - comment_nest--; - if (zflag && zflag <= 5) - fprintf(stream, "// END OF RESTRICTED FROM %s\n", b); - else if (comment_nest == 0) - fprintf(stream, " END OF RESTRICTED FROM %s */\n", b); - else - fprintf(stream, " END OF RESTRICTED FROM %s\n", b); - } - } - } - else if (complexType.complexContent->extension) - { const char *base = complexType.complexContent->extension->base; - xs__complexType *p = complexType.complexContent->extension->complexTypePtr(); - if (!anonymous) - fprintf(stream, "\n/// \"%s\":%s is a%s complexType with complexContent extension of %s.\n", URI?URI:"", name, complexType.abstract?"n abstract":"", base); - document(complexType.annotation); - operations(t); - if (anonymous) - { if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (fflag) - fprintf(stream, "class %s\n{ public:\n", t); - else // TODO: what to do if base class is in another namespace and elements must be qualified in XML payload? - { const char *baseURI = NULL; - if (p && p->schemaPtr()) - baseURI = p->schemaPtr()->targetNamespace; - fprintf(stream, "class %s : public %s\n{ public:\n", t, cname(NULL, baseURI, base)); - soapflag = true; - } - gen_inh(URI, p, anonymous); - if (complexType.complexContent->extension->group) - gen(URI, *complexType.complexContent->extension->group, NULL, NULL); - if (complexType.complexContent->extension->all) - gen(URI, *complexType.complexContent->extension->all, NULL, NULL); - if (complexType.complexContent->extension->sequence) - gen(URI, *complexType.complexContent->extension->sequence, NULL, NULL); - if (complexType.complexContent->extension->choice) - gen(URI, name, *complexType.complexContent->extension->choice, NULL, NULL); - gen(URI, complexType.complexContent->extension->attribute); - gen(URI, complexType.complexContent->extension->attributeGroup); - if (complexType.complexContent->extension->anyAttribute) - gen(URI, *complexType.complexContent->extension->anyAttribute); - } - else - fprintf(stream, "//\tunrecognized\n"); - } - else - { if (!anonymous) - fprintf(stream, "\n/// \"%s\":%s is a%s complexType.\n", URI?URI:"", name, complexType.abstract?"n abstract":""); - document(complexType.annotation); - operations(t); - if (anonymous) - { if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (pflag && complexType.name) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - if (complexType.all) - gen(URI, *complexType.all, NULL, NULL); - else if (complexType.choice) - gen(URI, name, *complexType.choice, NULL, NULL); - else if (complexType.sequence) - gen(URI, *complexType.sequence, NULL, NULL); - else if (complexType.any) - gen(URI, *complexType.any, NULL, NULL); - } - gen(URI, complexType.attribute); - gen(URI, complexType.attributeGroup); - if (complexType.anyAttribute) - gen(URI, *complexType.anyAttribute); - if (complexType.mixed - || ( complexType.complexContent - && complexType.complexContent->extension - && complexType.complexContent->extension->complexTypePtr() - && complexType.complexContent->extension->complexTypePtr()->mixed - )) - { 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"); - if (dflag) - { if (with_union) - fprintf(stream, pointerformat, "xsd__anyType", "__mixed"); - else - fprintf(stream, elementformat, "xsd__anyType", "__mixed"); - fprintf(stream, "0;\t///< Catch mixed content in DOM soap_dom_element linked node structure.\n"); - } - else - { fprintf(stream, elementformat, "_XML", "__mixed"); - fprintf(stream, "0;\t///< Catch mixed content in XML string\n"); - } - } - if (t) - modify(t); - if (!anonymous) - { if (!cflag - && !(pflag && complexType.name) - && !soapflag) - { if (!complexType.complexContent || !complexType.complexContent->extension || !complexType.complexContent->extension->complexTypePtr()) - { fprintf(stream, "/// A handle to the soap struct that manages this instance (automatically set)\n"); - fprintf(stream, pointerformat, "struct soap", "soap"); - fprintf(stream, ";\n"); - } - } - fprintf(stream, "};\n"); - } - scope.pop_back(); -} - -void Types::gen(const char *URI, const vector<xs__attribute>& attributes) -{ for (vector<xs__attribute>::const_iterator attribute = attributes.begin(); attribute != attributes.end(); ++attribute) - gen(URI, *attribute); -} - -void Types::gen(const char *URI, const xs__attribute& attribute) -{ const char *name, *type, *nameURI = NULL, *typeURI = NULL, *nameprefix = NULL, *typeprefix = NULL; - name = attribute.name; - type = attribute.type; - bool is_optional = attribute.use != required && attribute.use != default_ && attribute.use != fixed_ && !attribute.default_; - document(attribute.annotation); - if (!URI) - URI = attribute.schemaPtr()->targetNamespace; - if (attribute.form) - { if (*attribute.form == qualified) - nameURI = URI; - else - nameprefix = ":"; - } - if (URI && attribute.schemaPtr() && attribute.schemaPtr()->targetNamespace && strcmp(URI, attribute.schemaPtr()->targetNamespace)) - nameURI = attribute.schemaPtr()->targetNamespace; // handles attributeGroup defined in another namespace - if (attribute.attributePtr()) // attribute ref - { name = attribute.attributePtr()->name; - type = attribute.attributePtr()->type; - if (!type) - { type = name; - typeprefix = "_"; - } - if (attribute.attributePtr()->schemaPtr()) - { typeURI = attribute.attributePtr()->schemaPtr()->targetNamespace; - if (attribute.form && *attribute.form == unqualified) - nameprefix = ":"; - else if (zflag != 3 && zflag != 2 - && URI - && typeURI - && attribute.schemaPtr()->elementFormDefault == qualified - && !strcmp(URI, typeURI)) - nameprefix = NULL; - else if (zflag == 3 - && URI - && typeURI - && attribute.schemaPtr()->attributeFormDefault == unqualified - && !strcmp(URI, typeURI)) - nameprefix = NULL; - else - nameURI = typeURI; - } - fprintf(stream, "/// Attribute reference %s.\n", attribute.ref); - document(attribute.attributePtr()->annotation); - fprintf(stream, attributeformat, pname(is_optional, typeprefix, typeURI, type), aname(nameprefix, nameURI, name)); // make sure no name - type clash - } - else if (name && type) - { fprintf(stream, "/// Attribute %s of type %s.\n", name, type); - fprintf(stream, attributeformat, pname(is_optional, NULL, URI, type), aname(nameprefix, nameURI, name)); // make sure no name - type clash - } - else if (name && attribute.simpleTypePtr()) - { fprintf(stream, "@"); - gen(URI, name, *attribute.simpleTypePtr(), true); - // 8/1/09 Changed (is_optional && !cflag && !sflag) to is_optional - fprintf(stream, is_optional ? pointerformat : elementformat, "", aname(nameprefix, nameURI, name)); - } - else if (attribute.ref) - { fprintf(stream, "/// Imported attribute reference %s.\n", attribute.ref); - fprintf(stream, attributeformat, pname(is_optional, "_", NULL, attribute.ref), aname(NULL, NULL, attribute.ref)); - } - else - { fprintf(stream, "/// Attribute '%s' has no type or ref: assuming string content.\n", name?name:""); - fprintf(stream, attributeformat, tname(NULL, NULL, "xs:string"), aname(NULL, nameURI, name)); - } - switch (attribute.use) - { case prohibited: - fprintf(stream, " 0:0"); - break; - case required: - fprintf(stream, " 1"); - break; - default: - fprintf(stream, " 0"); - break; - } - if (attribute.default_ - || (attribute.fixed && !is_optional)) - { const char *value, *QName; - if (attribute.default_) - { value = attribute.default_; - QName = attribute.default__; - } - else - { value = attribute.fixed; - QName = attribute.fixed_; - } - const char *t = NULL; - if (!type && attribute.simpleTypePtr()) - { if (attribute.simpleTypePtr()->restriction && attribute.simpleTypePtr()->restriction->base) - { if (!attribute.simpleTypePtr()->restriction->enumeration.empty()) - { const char *s; - if (is_integer(value)) - fprintf(stream, " = %s", value); - else if (!*value) - fprintf(stream, " = 0"); - else if ((s = enames[Pair(gname(URI, name),value)])) - fprintf(stream, " = %s", s); - } - else - { const char *baseURI = NULL; - if (attribute.simpleTypePtr()->restriction->simpleTypePtr() && attribute.simpleTypePtr()->restriction->simpleTypePtr()->schemaPtr()) - baseURI = attribute.simpleTypePtr()->restriction->simpleTypePtr()->schemaPtr()->targetNamespace; - t = tname(NULL, baseURI, attribute.simpleTypePtr()->restriction->base); - } - } - } - if (type && !t) - t = tname(NULL, typeURI?typeURI:URI, type); - if (t) - { if (!strncmp(t, "unsigned ", 9)) - t += 9; - else if (!strncmp(t, "xsd__unsigned", 13)) - t += 13; - else if (!strncmp(t, "xsd__", 5)) - t += 5; - if (!strcmp(t, "bool") - || !strcmp(t, "byte") - || !strcmp(t, "Byte") - || !strcmp(t, "char") - || !strcmp(t, "double") - || !strcmp(t, "float") - || !strcmp(t, "int") - || !strcmp(t, "Int") - || !strcmp(t, "long") - || !strcmp(t, "Long") - || !strcmp(t, "LONG64") - || !strcmp(t, "short") - || !strcmp(t, "Short") - || !strcmp(t, "ULONG64")) - fprintf(stream, " = %s", value); - else if (!strncmp(t, "enum ", 5)) - { const char *s; - if (is_integer(value)) - fprintf(stream, " = %s", value); - else if (!*value) - fprintf(stream, " = 0"); - else if ((s = enames[Pair(t + 5,value)])) - fprintf(stream, " = %s", s); - } - else if (!strcmp(t, "char*") - || !strcmp(t, "char *") // not elegant - || !strcmp(t, "std::string") - || !strcmp(t, "std::string*") - || !strcmp(t, "std::string *")) // not elegant - fprintf(stream, " = \"%s\"", cstring(value)); - else if (!strcmp(t, "xsd__QName") && QName) // QName - fprintf(stream, " = \"%s\"", cstring(QName)); - } - if (attribute.default_) - fprintf(stream, ";\t///< Default value=\"%s\".\n", value); - else - fprintf(stream, ";\t///< Fixed required value=\"%s\".\n", value); - } - else if (attribute.fixed) - fprintf(stream, ";\t///< Fixed optional value=\"%s\".\n", attribute.fixed); - else if (attribute.use == required) - fprintf(stream, ";\t///< Required attribute.\n"); - else if (attribute.use == prohibited) - fprintf(stream, ";\t///< Prohibited attribute.\n"); - else - fprintf(stream, ";\t///< Optional attribute.\n"); -} - -void Types::gen(const char *URI, const vector<xs__attributeGroup>& attributeGroups) -{ for (vector<xs__attributeGroup>::const_iterator attributeGroup = attributeGroups.begin(); attributeGroup != attributeGroups.end(); ++attributeGroup) - { const xs__attributeGroup *ag = &*attributeGroup; - if (ag->attributeGroupPtr()) // attributeGroup ref - ag = ag->attributeGroupPtr(); - fprintf(stream, "/// Begin attributeGroup %s.\n", ag->name?ag->name:ag->ref?ag->ref:""); - gen(URI, ag->attribute); - gen(URI, ag->attributeGroup); - if (ag->anyAttribute) - gen(URI, *ag->anyAttribute); - fprintf(stream, "/// End of attributeGroup %s.\n", ag->name?ag->name:ag->ref?ag->ref:""); - } -} - -void Types::gen(const char *URI, const vector<xs__all>& alls) -{ for (vector<xs__all>::const_iterator all = alls.begin(); all != alls.end(); ++all) - gen(URI, *all, NULL, NULL); -} - -void Types::gen(const char *URI, const xs__all& all, const char *minOccurs, const char *maxOccurs) -{ bool tmp_union1 = with_union; - bool tmp_union2 = fake_union; - with_union = false; - fake_union = false; - gen(URI, all.element, minOccurs, maxOccurs); - with_union = tmp_union1; - fake_union = tmp_union2; -} - -void Types::gen(const char *URI, const vector<xs__contents>& contents) -{ for (vector<xs__contents>::const_iterator content = contents.begin(); content != contents.end(); ++content) - { switch ((*content).__union) - { case SOAP_UNION_xs__union_content_element: - if ((*content).__content.element) - gen(URI, *(*content).__content.element, true, NULL, NULL); - break; - case SOAP_UNION_xs__union_content_group: - if ((*content).__content.group) - gen(URI, *(*content).__content.group, NULL, NULL); - break; - case SOAP_UNION_xs__union_content_choice: - if ((*content).__content.choice) - gen(URI, NULL, *(*content).__content.choice, NULL, NULL); - break; - case SOAP_UNION_xs__union_content_sequence: - if ((*content).__content.sequence) - gen(URI, *(*content).__content.sequence, NULL, NULL); - break; - case SOAP_UNION_xs__union_content_any: - if ((*content).__content.any) - gen(URI, *(*content).__content.any, NULL, NULL); - break; - } - } -} - -void Types::gen(const char *URI, const xs__seqchoice& sequence, const char *minOccurs, const char *maxOccurs) -{ const char *s = NULL; - char *t = NULL; - bool tmp_union = with_union; - with_union = false; - if (sequence.minOccurs) - minOccurs = sequence.minOccurs; - if (sequence.maxOccurs) - maxOccurs = sequence.maxOccurs; - if ((minOccurs && strcmp(minOccurs, "1")) - || (maxOccurs && strcmp(maxOccurs, "1"))) - { fprintf(stream, "/// SEQUENCE <xs:sequence"); - if (minOccurs) - fprintf(stream, " minOccurs=\"%s\"", minOccurs); - if (maxOccurs) - fprintf(stream, " maxOccurs=\"%s\"", maxOccurs); - fprintf(stream, ">\n"); - document(sequence.annotation); - s = sname(URI, "sequence"); - t = (char*)emalloc(strlen(s)+2); - strcpy(t, "_"); - strcat(t, s); - s = strstr(s, "__"); - if (!s) - s = t; - if (cflag || sflag || zflag == 2) - { fprintf(stream, sizeformat, "int", s + 1); - if (!fake_union && minOccurs) - fprintf(stream, " %s", minOccurs); - if (maxOccurs - && strcmp(maxOccurs, "1") - && is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - } - else - { fprintf(stream, elementformat, "std::vector<", ""); - fprintf(stream, "\n"); - } - if (cflag) - fprintf(stream, " struct %s\n {\n", t); - else - fprintf(stream, " class %s\n {\n", t); - } - else - { if (fake_union) - fprintf(stream, "/// SEQUENCE <xs:sequence>\n"); - document(sequence.annotation); - } - gen(URI, sequence.__contents); - if (s) - { if (cflag || sflag || zflag == 2) - fprintf(stream, pointerformat, "}", s); - else - { fprintf(stream, elementformat, "}>", s); - if (!fake_union && minOccurs) - fprintf(stream, " %s", minOccurs); - if (maxOccurs - && strcmp(maxOccurs, "1") - && is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - } - fprintf(stream, ";\n"); - } - if (s || fake_union) - fprintf(stream, "// END OF SEQUENCE\n"); - with_union = tmp_union; -} - -void Types::gen(const char *URI, const vector<xs__element>& elements, const char *minOccurs, const char *maxOccurs) -{ for (vector<xs__element>::const_iterator element = elements.begin(); element != elements.end(); ++element) - gen(URI, *element, true, minOccurs, maxOccurs); -} - -void Types::gen(const char *URI, const xs__element& element, bool substok, const char *minOccurs, const char *maxOccurs) -{ const char *name, *type, *nameURI = NULL, *typeURI = NULL, *nameprefix = NULL, *typeprefix = NULL; - name = element.name; - type = element.type; - document(element.annotation); - if (!URI) - URI = element.schemaPtr()->targetNamespace; - if (element.minOccurs) - minOccurs = element.minOccurs; - if (element.maxOccurs) - maxOccurs = element.maxOccurs; - if (element.xmime__expectedContentTypes) - fprintf(stream, "/// MTOM attachment with content types %s.\n", element.xmime__expectedContentTypes); - if (element.form) - { if (*element.form == qualified) - nameURI = URI; - else - nameprefix = ":"; - } - if (element.elementPtr()) // element ref - { name = element.elementPtr()->name; - type = element.elementPtr()->type; - if (!type) - { type = name; - typeprefix = "_"; - } - if (element.elementPtr()->schemaPtr()) - { typeURI = element.elementPtr()->schemaPtr()->targetNamespace; - if (element.form && *element.form == unqualified) - nameprefix = ":"; - else if (zflag != 3 && zflag != 2 - && URI - && typeURI - && element.schemaPtr()->elementFormDefault == qualified - && !strcmp(URI, typeURI)) - nameprefix = NULL; - else if (zflag == 3 - && URI - && typeURI - && element.schemaPtr()->elementFormDefault == unqualified - && !strcmp(URI, typeURI)) - nameprefix = NULL; - else - nameURI = typeURI; - } - document(element.elementPtr()->annotation); - if (element.elementPtr()->xmime__expectedContentTypes) - fprintf(stream, "/// MTOM attachment with content types %s.\n", element.elementPtr()->xmime__expectedContentTypes); - if (substok && element.elementPtr()->abstract) - { fprintf(stream, "/// Reference %s to abstract element.\n", element.ref); - gen_substitutions(URI, element); - } - else if (substok - && element.elementPtr()->substitutionsPtr() - && !element.elementPtr()->substitutionsPtr()->empty()) - { if (vflag) - fprintf(stderr, "\nWarning: element ref '%s' stands as the head of a substitutionGroup but is not declared abstract\n", element.ref); - gen_substitutions(URI, element); - } - else if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { const char *s = tnameptr(cflag && zflag != 1, typeprefix, typeURI, type); - if (cflag || sflag) - { fprintf(stream, "/// Size of the dynamic array of %s is %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, sizeformat, "int", aname(NULL, NULL, name)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - if (cflag && zflag != 1) - { fprintf(stream, "/// Array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name)); - } - else - { fprintf(stream, "/// Pointer to array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name)); - } - } - else - { fprintf(stream, "/// Vector of %s element refs with length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - if (with_union) - fprintf(stream, pointervectorformat, s, aname(nameprefix, nameURI, name)); - else - fprintf(stream, vectorformat, s, aname(nameprefix, nameURI, name)); - } - } - else - { fprintf(stream, "/// Element reference %s.\n", element.ref); - fprintf(stream, elementformat, pname((with_union && !cflag && !is_basetypeforunion(typeprefix, typeURI, type)) || fake_union || is_nillable(element), typeprefix, typeURI, type), aname(nameprefix, nameURI, name)); - } - } - else if (name && type) - { if (substok && element.abstract) - { fprintf(stream, "/// Abstract element %s of type %s.\n", name, type); - gen_substitutions(URI, element); - } - else if (substok - && element.substitutionsPtr() - && !element.substitutionsPtr()->empty()) - { if (vflag) - fprintf(stderr, "\nWarning: element '%s' stands as the head of a substitutionGroup but is not declared abstract\n", name); - gen_substitutions(URI, element); - } - else if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { const char *s = tnameptr(cflag && zflag != 1, NULL, URI, type); - if (cflag || sflag) - { fprintf(stream, "/// Size of array of %s is %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, sizeformat, "int", aname(NULL, NULL, name)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - if (cflag && zflag != 1) - { fprintf(stream, "/// Array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name)); - } - else - { fprintf(stream, "/// Pointer to array %s of length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name)); - } - } - else - { fprintf(stream, "/// Vector of %s with length %s..%s\n", s, minOccurs ? minOccurs : "1", maxOccurs); - if (with_union) - fprintf(stream, pointervectorformat, s, aname(nameprefix, nameURI, name)); - else - fprintf(stream, vectorformat, s, aname(nameprefix, nameURI, name)); - } - } - else - { fprintf(stream, "/// Element %s of type %s.\n", name, type); - fprintf(stream, elementformat, pname((with_union && !cflag && !is_basetypeforunion(NULL, URI, type)) || (fake_union && !element.default_) || is_nillable(element), NULL, URI, type), aname(nameprefix, nameURI, name)); - } - } - else if (name && element.simpleTypePtr()) - { const char *s = ""; - document(element.simpleTypePtr()->annotation); - if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { if (cflag || sflag) - { fprintf(stream, "/// Size of %s array is %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, sizeformat, "int", aname(NULL, NULL, name)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - } - else - { s = ">"; - fprintf(stream, "/// Vector of %s with length %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, vectorformat_open, "\n"); - } - } - gen(URI, name, *element.simpleTypePtr(), true); - if (is_nillable(element) - || ((cflag || sflag ) && maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - || (with_union && !cflag) - || (fake_union && !element.default_)) - fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name)); - else - fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name)); - } - else if (name && element.complexTypePtr()) - { const char *s = "}"; - document(element.complexTypePtr()->annotation); - if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { if (cflag || sflag) - { fprintf(stream, "/// Size of %s array is %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, sizeformat, "int", aname(NULL, NULL, name)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - } - else - { s = "}>"; - fprintf(stream, "/// Vector of %s with length %s..%s\n", name, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, vectorformat_open, "\n"); - } - } - gen(URI, name, *element.complexTypePtr(), true); - if (is_nillable(element) - || ((cflag || sflag ) && maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - || (with_union && !cflag) - || (fake_union && !element.default_)) - fprintf(stream, pointerformat, s, aname(nameprefix, nameURI, name)); - else - fprintf(stream, elementformat, s, aname(nameprefix, nameURI, name)); - } - else if (element.ref) - { fprintf(stream, "/// Imported element reference %s.\n", element.ref); - if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { if (cflag || sflag) - { fprintf(stream, "/// Size of %s array is %s..%s\n", element.ref, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, sizeformat, "int", aname(NULL, NULL, element.ref)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - fprintf(stream, pointerformat, pname(true, "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref)); - } - else - { fprintf(stream, "/// Vector of %s with length %s..%s\n", element.ref, minOccurs ? minOccurs : "1", maxOccurs); - fprintf(stream, vectorformat, pname(false, "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref)); - } - } - else - fprintf(stream, elementformat, pname((with_union && !cflag) || fake_union || is_nillable(element), "_", NULL, element.ref), aname(nameprefix, nameURI, element.ref)); - } - else if (name) - { fprintf(stream, "/// Element '%s' has no type or ref (empty or with XML content).\n", name?name:""); - if (maxOccurs && strcmp(maxOccurs, "1")) // maxOccurs != "1" - { if (cflag || sflag) - { fprintf(stream, sizeformat, "int", aname(NULL, NULL, name)); - fprintf(stream, " %s", fake_union ? "0" : minOccurs ? minOccurs : "1"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - fprintf(stream, "/// Pointer to array of XML.\n"); - fprintf(stream, pointerformat, "_XML", aname(NULL, nameURI, name)); - } - else - { fprintf(stream, "/// Vector of XML with length %s..%s\n", minOccurs ? minOccurs : "1", maxOccurs); - if (with_union) - fprintf(stream, pointervectorformat, "_XML", aname(NULL, nameURI, name)); - else - fprintf(stream, vectorformat, "_XML", aname(NULL, nameURI, name)); - } - } - else - fprintf(stream, elementformat, "_XML", aname(NULL, nameURI, name)); - } - else - fprintf(stream, "/// Element has no name, type, or ref."); - if (!substok - || ( !(element.elementPtr() && element.elementPtr()->abstract) - && !(element.substitutionsPtr() && !element.substitutionsPtr()->empty()) - && !(element.elementPtr() && element.elementPtr()->substitutionsPtr() && !element.elementPtr()->substitutionsPtr()->empty()) - )) - { if (!fake_union && !minOccurs && !element.nillable && !element.default_ && !element.abstract) - fprintf(stream, " 1"); - else if (!fake_union && minOccurs) - fprintf(stream, " %s", minOccurs); - if (maxOccurs && strcmp(maxOccurs, "1") && is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - if (element.default_ - || ( element.fixed - && !fake_union - && (!minOccurs || !strcmp(minOccurs, "1")) - && (!maxOccurs || !strcmp(maxOccurs, "1")) - )) - { // determine whether the element can be assigned a default value, this is dependent on the choice of mapping for primitive types - const char *value, *QName; - if (element.default_) - { value = element.default_; - QName = element.default__; - } - else - { value = element.fixed; - QName = element.fixed_; - } - if (type) - { const char *t = tname(NULL, typeURI?typeURI:URI, type); - if (!strncmp(t, "unsigned ", 9)) - t += 9; - else if (!strncmp(t, "xsd__unsigned", 13)) - t += 13; - else if (!strncmp(t, "xsd__", 5)) - t += 5; - if (!strcmp(t, "bool") - || !strcmp(t, "byte") - || !strcmp(t, "Byte") - || !strcmp(t, "char") - || !strcmp(t, "double") - || !strcmp(t, "float") - || !strcmp(t, "int") - || !strcmp(t, "Int") - || !strcmp(t, "long") - || !strcmp(t, "Long") - || !strcmp(t, "LONG64") - || !strcmp(t, "short") - || !strcmp(t, "Short") - || !strcmp(t, "ULONG64")) - fprintf(stream, " = %s", value); - else if (!strncmp(t, "enum ", 5)) - { const char *s; - if (is_integer(value)) - fprintf(stream, " = %s", value); - else if (!*value) - fprintf(stream, " = 0"); - else if ((s = enames[Pair(t + 5, value)])) - fprintf(stream, " = %s", s); - } - else if (!strcmp(t, "char*") - || !strcmp(t, "char *") // not elegant - || !strcmp(t, "std::string") - || !strcmp(t, "std::string*") - || !strcmp(t, "std::string *")) // not elegant - fprintf(stream, " = \"%s\"", cstring(value)); - else if (!strcmp(t, "xsd__QName") && QName) // QName - fprintf(stream, " = \"%s\"", cstring(QName)); - } - if (element.default_) - fprintf(stream, ";\t///< Default value=\"%s\".\n", value); - else - fprintf(stream, ";\t///< Fixed required value=\"%s\".\n", value); - } - else if (element.nillable) - fprintf(stream, ";\t///< Nillable pointer.\n"); - else if (!fake_union && (!minOccurs || !strcmp(minOccurs, "1")) && (!maxOccurs || !strcmp(maxOccurs, "1"))) - fprintf(stream, ";\t///< Required element.\n"); - else if (element.fixed) - fprintf(stream, ";\t///< Fixed optional value=\"%s\".\n", element.fixed); - else if (!fake_union && minOccurs && !strcmp(minOccurs, "0") && (!maxOccurs || !strcmp(maxOccurs, "1"))) - fprintf(stream, ";\t///< Optional element.\n"); - else - fprintf(stream, ";\n"); - } -} - -void Types::gen(const char *URI, const vector<xs__group>& groups) -{ for (vector<xs__group>::const_iterator group = groups.begin(); group != groups.end(); ++group) - gen(URI, *group, NULL, NULL); -} - -void Types::gen(const char *URI, const xs__group& group, const char *minOccurs, const char *maxOccurs) -{ if (group.minOccurs) - minOccurs = group.minOccurs; - if (group.maxOccurs) - maxOccurs = group.maxOccurs; - if (group.groupPtr()) - { if (group.schemaPtr() == group.groupPtr()->schemaPtr()) - gen(URI, *group.groupPtr(), minOccurs, maxOccurs); - else - gen(group.groupPtr()->schemaPtr()->targetNamespace, *group.groupPtr(), minOccurs, maxOccurs); - } - else - { fprintf(stream, "/// GROUP <xs:group name=\"%s\"", group.name ? group.name : ""); - if (minOccurs) - fprintf(stream, " minOccurs=\"%s\"", minOccurs); - if (maxOccurs) - fprintf(stream, " maxOccurs=\"%s\"", maxOccurs); - fprintf(stream, ">\n"); - document(group.annotation); - if (group.all) - gen(URI, *group.all, minOccurs, maxOccurs); - else if (group.choice) - gen(URI, NULL, *group.choice, minOccurs, maxOccurs); - else if (group.sequence) - gen(URI, *group.sequence, minOccurs, maxOccurs); - fprintf(stream, "// END OF GROUP\n"); - } -} - -void Types::gen(const char *URI, const char *name, const xs__seqchoice& choice, const char *minOccurs, const char *maxOccurs) -{ const char *r = NULL, *s = NULL, *t = NULL; - bool use_union = !uflag; - bool wrap_union = false; - bool tmp_union; - if (!URI && choice.schemaPtr()) - URI = choice.schemaPtr()->targetNamespace; - fprintf(stream, "/// CHOICE <xs:choice"); - if (choice.minOccurs) - minOccurs = choice.minOccurs; - if (choice.maxOccurs) - maxOccurs = choice.maxOccurs; - if (minOccurs) - fprintf(stream, " minOccurs=\"%s\"", minOccurs); - if (maxOccurs) - fprintf(stream, " maxOccurs=\"%s\"", maxOccurs); - fprintf(stream, ">\n"); - document(choice.annotation); - for (vector<xs__contents>::const_iterator c1 = choice.__contents.begin(); c1 != choice.__contents.end(); ++c1) - { if ((*c1).__union == SOAP_UNION_xs__union_content_group - || (*c1).__union == SOAP_UNION_xs__union_content_sequence) - { fprintf(stream, "/// Note: <xs:choice> with embedded <xs:sequence> or <xs:group> prevents the use of a union\n"); - use_union = false; - break; - } - } - if (use_union && (cflag || sflag)) - { for (vector<xs__contents>::const_iterator c2 = choice.__contents.begin(); c2 != choice.__contents.end(); ++c2) - { if ((*c2).__union == SOAP_UNION_xs__union_content_element - && (*c2).__content.element - && (*c2).__content.element->maxOccurs - && strcmp((*c2).__content.element->maxOccurs, "1")) - { fprintf(stream, "/// Note: <xs:choice> of element with maxOccurs>1 prevents the use of a union\n"); - use_union = false; - break; - } - } - } - t = uname(URI); - s = strstr(t, "__union"); - if (s) - r = s + 7; - if (!r || !*r) - { r = t; - s = "__union"; - } - if (maxOccurs && strcmp(maxOccurs, "1")) - { if (with_union) - { // Generate a wrapper when we need a union within a union - wrap_union = true; - fprintf(stream, " struct __%s\n {\n", t); - } - fprintf(stream, sizeformat, "int", r); - fprintf(stream, " %s", minOccurs ? minOccurs : "0"); - if (is_integer(maxOccurs)) - fprintf(stream, ":%s", maxOccurs); - fprintf(stream, ";\n"); - if (cflag) - fprintf(stream, " struct _%s\n {\n", t); - else - fprintf(stream, " class _%s\n {\n", t); - } - if (use_union) - { if (!with_union || wrap_union) - { fprintf(stream, choiceformat, "int", r); - if (minOccurs) - fprintf(stream, " %s", minOccurs); - fprintf(stream, ";\t///< Union %s selector: set to SOAP_UNION_%s_<fieldname>%s\n", t, t, minOccurs && !strcmp(minOccurs, "0") ? " or 0" : ""); - if (name) - fprintf(stream, "/// Union for choice in type %s\n", cname(NULL, URI, name)); - fprintf(stream, " union %s\n {\n", t); - } - tmp_union = with_union; - with_union = true; - } - else - { tmp_union = fake_union; - fake_union = true; - } - gen(URI, choice.__contents); - if (use_union) - { with_union = tmp_union; - if (!with_union || wrap_union) - fprintf(stream, elementformat, "}", s+2); - } - else - fake_union = tmp_union; - if (maxOccurs && strcmp(maxOccurs, "1")) - { if (use_union) - fprintf(stream, ";\n"); - fprintf(stream, pointerformat, "}", s); - } - fprintf(stream, ";\n"); - if (wrap_union) - { fprintf(stream, elementformat, "}", s); - fprintf(stream, ";\n"); - } - fprintf(stream, "// END OF CHOICE\n"); -} - -void Types::gen(const char *URI, const vector<xs__any>& anys) -{ for (vector<xs__any>::const_iterator any = anys.begin(); any != anys.end(); ++any) - gen(URI, *any, NULL, NULL); -} - -void Types::gen(const char *URI, const xs__any& any, const char *minOccurs, const char *maxOccurs) -{ fprintf(stream, "/// TODO: <any"); - if (any.namespace_) - fprintf(stream, " namespace=\"%s\"", any.namespace_); - if (any.minOccurs) - minOccurs = any.minOccurs; - if (any.maxOccurs) - maxOccurs = any.maxOccurs; - if (minOccurs) - fprintf(stream, " minOccurs=\"%s\"", minOccurs); - if (maxOccurs) - fprintf(stream, " maxOccurs=\"%s\"", maxOccurs); - 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"); - if (!xflag) - { if (maxOccurs && strcmp(maxOccurs, "1")) - { fprintf(stream, "/// Size of the array of XML or DOM nodes is %s..%s\n", minOccurs ? minOccurs : "1", maxOccurs); - if (cflag || sflag) - { if (!with_union) - { fprintf(stream, sizeformat, "int", ""); - fprintf(stream, "0;\n"); - fprintf(stream, elementformat, pname(true, NULL, NULL, "xsd:any"), "__any"); - } - else - fprintf(stream, elementformat, tname(NULL, NULL, "xsd:any"), "__any"); - } - else if (with_union) - fprintf(stream, pointervectorformat, tname(NULL, NULL, "xsd:any"), "__any"); - else - fprintf(stream, vectorformat, tname(NULL, NULL, "xsd:any"), "__any"); - } - else - fprintf(stream, elementformat, pname(with_union, NULL, NULL, "xsd:any"), "__any"); - if (dflag) - fprintf(stream, "0;\t///< Catch any element content in DOM.\n"); - else - fprintf(stream, "0;\t///< Catch any element content in XML string.\n"); - } -} - -void Types::gen(const char *URI, const xs__anyAttribute& anyAttribute) -{ if (anyAttribute.namespace_) - fprintf(stream, "/// <anyAttribute namespace=\"%s\">\n", anyAttribute.namespace_); - 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"); - if (!xflag) - { const char *t = tname(NULL, NULL, "xsd:anyAttribute"); - fprintf(stream, attributeformat, t, "__anyAttribute"); - if (dflag) - fprintf(stream, ";\t///< Store anyAttribute content in DOM soap_dom_attribute linked node structure.\n"); - else - fprintf(stream, ";\t///< A placeholder that has no effect: please see comment.\n"); - } -} - -void Types::gen_inh(const char *URI, const xs__complexType *complexType, bool anonymous) -{ const xs__complexType *p = complexType; - if (!p) - return; - const char *pURI; - if (p->schemaPtr()) - pURI = p->schemaPtr()->targetNamespace; - else - pURI = URI; - const char *b = cname(NULL, pURI, p->name); - if (p->complexContent && p->complexContent->extension) - gen_inh(URI, p->complexContent->extension->complexTypePtr(), anonymous); - if (cflag || fflag || anonymous) - fprintf(stream, "/// INHERITED FROM %s:\n", b); - else if (comment_nest == 0) - fprintf(stream, "/* INHERITED FROM %s:\n", b); - else - fprintf(stream, " INHERITED FROM %s:\n", b); - comment_nest++; - if (cflag || fflag) - pURI = URI; // if base ns != derived ns then qualify elts - if (p->complexContent && p->complexContent->extension) - { if (p->complexContent->extension->group) - gen(pURI, *p->complexContent->extension->group, NULL, NULL); - if (p->complexContent->extension->all) - gen(pURI, *p->complexContent->extension->all, NULL, NULL); - if (p->complexContent->extension->sequence) - gen(pURI, *p->complexContent->extension->sequence, NULL, NULL); - if (p->complexContent->extension->choice) - gen(pURI, p->name, *p->complexContent->extension->choice, NULL, NULL); - gen(pURI, p->complexContent->extension->attribute); - gen(pURI, p->complexContent->extension->attributeGroup); - if (p->complexContent->extension->anyAttribute) - gen(pURI, *p->complexContent->extension->anyAttribute); - } - else - { if (p->all) - gen(pURI, p->all->element, NULL, NULL); - else if (p->all) - gen(pURI, *p->all, NULL, NULL); - else if (p->choice) - gen(pURI, p->name, *p->choice, NULL, NULL); - else if (p->sequence) - gen(pURI, *p->sequence, NULL, NULL); - else if (p->any) - gen(pURI, *p->any, NULL, NULL); - gen(pURI, p->attribute); - gen(pURI, p->attributeGroup); - if (p->anyAttribute) - gen(pURI, *p->anyAttribute); - } - modify(b); - comment_nest--; - if (cflag || fflag || anonymous) - fprintf(stream, "// END OF INHERITED FROM %s\n", b); - else if (comment_nest == 0) - fprintf(stream, " END OF INHERITED FROM %s */\n", b); - else - fprintf(stream, " END OF INHERITED FROM %s\n", b); -} - -void Types::gen_soap_array(const char *name, const char *t, const char *item, const char *type) -{ char *tmp = NULL, *dims = NULL, size[8]; - if (type) - { tmp = (char*)emalloc(strlen(type) + 1); - strcpy(tmp, type); - } - *size = '\0'; - if (tmp) - dims = strrchr(tmp, '['); - if (dims) - *dims++ = '\0'; - fprintf(stream, "/// SOAP encoded array of %s\n", tmp ? tmp : "xs:anyType"); - if (cflag) - fprintf(stream, "struct %s\n{\n", t); - else if (pflag) - fprintf(stream, "class %s : public xsd__anyType\n{ public:\n", t); - else - fprintf(stream, "class %s\n{ public:\n", t); - if (dims) - { char *s = strchr(dims, ']'); - if (s && s != dims) - sprintf(size, "[%d]", (int)(s - dims + 1)); - } - if (tmp) - { if (strchr(tmp, '[') != NULL) - { gen_soap_array(NULL, "", item, tmp); - fprintf(stream, arrayformat, "}", item ? aname(NULL, NULL, item) : ""); - fprintf(stream, ";\n"); - } - else - { const char *s = pname(!is_basetype(NULL, NULL, tmp), NULL, NULL, tmp); - fprintf(stream, "/// Pointer to array of %s.\n", s); - fprintf(stream, arrayformat, s, item ? aname(NULL, NULL, item) : ""); - fprintf(stream, ";\n"); - } - if (*size) - fprintf(stream, "/// Size of the multidimensional dynamic array with dimensions=%s\n", size); - else - fprintf(stream, "/// Size of the dynamic array.\n"); - fprintf(stream, arraysizeformat, "int", size); - fprintf(stream, ";\n/// Offset for partially transmitted arrays (uncomment only when required).\n"); - fprintf(stream, arrayoffsetformat, "int", size); - fprintf(stream, ";\n"); - } - else - { // TODO: how to handle generic SOAP array? E.g. as an array of anyType? - fprintf(stream, "// TODO: add declarations to handle generic SOAP-ENC:Array (array of anyType)\n"); - } -} - -void Types::gen_substitutions(const char *URI, const xs__element &element) -{ const std::vector<xs__element*> *substitutions; - const char *name; - const char *r = NULL, *s = NULL; - bool use_union = !uflag; - bool wrap_union = false; - bool tmp_union; - bool abstract = false; - if (!URI && element.schemaPtr()) - URI = element.schemaPtr()->targetNamespace; - if (element.elementPtr()) - { name = element.elementPtr()->name; - substitutions = element.elementPtr()->substitutionsPtr(); - abstract = element.elementPtr()->abstract; - if (!abstract && element.elementPtr()->complexTypePtr()) - abstract = element.elementPtr()->complexTypePtr()->abstract; - } - else - { name = element.name; - substitutions = element.substitutionsPtr(); - abstract = element.abstract; - if (!abstract && element.complexTypePtr()) - abstract = element.complexTypePtr()->abstract; - } - fprintf(stream, "/// CHOICE OF SUBSTITUTIONS <xs:element substitutionGroup=\"%s\"", name); - if (element.minOccurs) - fprintf(stream, " minOccurs=\"%s\"", element.minOccurs); - if (element.maxOccurs) - fprintf(stream, " maxOccurs=\"%s\"", element.maxOccurs); - fprintf(stream, "> with elements"); - for (std::vector<xs__element*>::const_iterator i1 = substitutions->begin(); i1 != substitutions->end(); ++i1) - fprintf(stream, " <%s>", (*i1)->name); - fprintf(stream, "\n"); - if (use_union) - { const char *t = uname(URI); - // TODO: could reuse the union instead of generating a new one each time! - s = strstr(t, "__union"); - if (!s) - s = "__union"; - r = aname(NULL, NULL, name); - if (element.maxOccurs && strcmp(element.maxOccurs, "1")) - { if (with_union) - { // Generate a wrapper when we need a union within a union - wrap_union = true; - fprintf(stream, " struct __%s\n {\n", t); - } - fprintf(stream, sizeformat, "int", r); - fprintf(stream, " %s", element.minOccurs ? element.minOccurs : "0"); - if (is_integer(element.maxOccurs)) - fprintf(stream, ":%s", element.maxOccurs); - fprintf(stream, ";\n"); - if (cflag) - fprintf(stream, " struct _%s\n {\n", t); - else - fprintf(stream, " class _%s\n {\n", t); - } - if (!with_union || wrap_union) - { fprintf(stream, choiceformat, "int", r); - fprintf(stream, " %s", element.minOccurs ? element.minOccurs : "0"); - fprintf(stream, ";\t///< Union %s selector: set to SOAP_UNION_%s_<fieldname>%s\n", t, t, element.minOccurs && !strcmp(element.minOccurs, "0") ? " or 0" : ""); - fprintf(stream, "/// Union for substitutionGroup=\"%s\"\n", name); - fprintf(stream, " union %s\n {\n", t); - } - tmp_union = with_union; - with_union = true; - } - else - { tmp_union = fake_union; - fake_union = true; - } - if (!abstract) - gen(URI, element, false, NULL, NULL); - for (vector<xs__element*>::const_iterator i2 = substitutions->begin(); i2 != substitutions->end(); ++i2) - gen(URI, *(*i2), true, NULL, NULL); // substitutions are recursive? - if (use_union) - { with_union = tmp_union; - if (!with_union || wrap_union) - { fprintf(stream, elementformat, "}", s); - fprintf(stream, ";\n"); - } - if (element.maxOccurs && strcmp(element.maxOccurs, "1")) - { fprintf(stream, ";\n"); - fprintf(stream, pointerformat, "}", s); - fprintf(stream, ";\n"); - } - if (wrap_union) - { fprintf(stream, elementformat, "}", s); - fprintf(stream, ";\n"); - } - } - else - fake_union = tmp_union; - fprintf(stream, "// END OF CHOICE OF SUBSTITUTIONS\n"); -} - -void Types::document(const xs__annotation *annotation) -{ if (annotation && annotation->documentation) - { fprintf(stream, "/// @brief"); - documentation(annotation->documentation); - } -} - -void Types::modify(const char *name) -{ // TODO: consider support removal of elements/attributes with ns__X = $- Y - const char *s = modtypemap[name]; - if (s) - { while (*s) - { if (*s++ == '$') - fprintf(stream, "/// Member declared in %s\n ", mapfile); - s = format(s); - } - } -} - -const char* Types::format(const char *text) -{ const char *s = text; - if (!s) - return NULL; - while (*s && *s != '$') - { if (*s == '\\') - { switch (s[1]) - { case 'n': - fputc('\n', stream); - break; - case 't': - fputc('\t', stream); - break; - default: - fputc(s[1], stream); - } - s++; - } - else - fputc(*s, stream); - s++; - } - fputc('\n', stream); - return s; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Type map file parsing -// -//////////////////////////////////////////////////////////////////////////////// - -static char *getline(char *s, size_t n, FILE *fd) -{ int c; - char *t = s; - if (n) - n--; - for (;;) - { c = fgetc(fd); - if (c == '\r') - continue; - if (c == '\\') - { c = fgetc(fd); - if (c == '\r') - c = fgetc(fd); - if (c < ' ') - continue; - if (n) - { *t++ = '\\'; - n--; - } - } - if (c == '\n' || c == EOF) - break; - if (n) - { *t++ = c; - n--; - } - } - *t++ = '\0'; - if (!*s && c == EOF) - return NULL; - return s; -} - -static const char *nonblank(const char *s) -{ while (*s && isspace(*s)) - s++; - return s; -} - -static const char *fill(char *t, int n, const char *s, int e) -{ int i = n; - s = nonblank(s); - while (*s && *s != e && --i) - *t++ = *s++; - while (*s && *s != e) - s++; - if (*s) - s++; - i = n - i; - if (i == 0) - *t = '\0'; - else - { while (isspace(*--t) && i--) - ; - t[1] = '\0'; - } - return s; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Miscellaneous -// -//////////////////////////////////////////////////////////////////////////////// - -static const char *utf8(char *t, const char *s) -{ unsigned int c = 0; - unsigned int c1, c2, c3, c4; - c = (unsigned char)*s; - if (c >= 0x80) - { c1 = (unsigned char)*++s; - if (c1 < 0x80) - s--; - else - { c1 &= 0x3F; - if (c < 0xE0) - c = ((c & 0x1F) << 6) | c1; - else - { c2 = (unsigned char)*++s & 0x3F; - if (c < 0xF0) - c = ((c & 0x0F) << 12) | (c1 << 6) | c2; - else - { c3 = (unsigned char)*++s & 0x3F; - if (c < 0xF8) - c = ((c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3; - else - { c4 = (unsigned char)*++s & 0x3F; - if (c < 0xFC) - c = ((c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; - else - c = ((c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (*++s & 0x3F); - } - } - } - } - } - sprintf(t, "_x%.4x", c); - return s; -} - -static const char *cstring(const char *s) -{ size_t n; - char *t; - const char *r; - for (n = 0, r = s; *r; n++, r++) - if (*r == '"' || *r == '\\') - n++; - else if (*r < 32) - n += 3; - r = t = (char*)emalloc(n + 1); - for (; *s; s++) - { if (*s == '"' || *s == '\\') - { *t++ = '\\'; - *t++ = *s; - } - else if (*s < 32) - { sprintf(t, "\\%03o", (unsigned int)(unsigned char)*s); - t += 4; - } - else - *t++ = *s; - } - *t = '\0'; - return r; -} - -static const char *xstring(const char *s) -{ size_t n; - char *t; - const char *r; - for (n = 0, r = s; *r; n++, r++) - { if (*r < 32 || *r >= 127) - n += 4; - else if (*r == '<' || *r == '>') - n += 3; - else if (*r == '&') - n += 4; - else if (*r == '"') - n += 5; - else if (*r == '\\') - n += 1; - } - r = t = (char*)emalloc(n + 1); - for (; *s; s++) - { if (*s < 32 || *s >= 127) - { sprintf(t, "&#%.2x;", (unsigned char)*s); - t += 5; - } - else if (*s == '<') - { strcpy(t, "<"); - t += 4; - } - else if (*s == '>') - { strcpy(t, ">"); - t += 4; - } - else if (*s == '&') - { strcpy(t, "&"); - t += 5; - } - else if (*s == '"') - { strcpy(t, """); - t += 6; - } - else if (*s == '\\') - { strcpy(t, "\\\\"); - t += 2; - } - else - *t++ = *s; - } - *t = '\0'; - return r; -} - -static LONG64 to_integer(const char *s) -{ LONG64 n; -#ifdef HAVE_STRTOLL - char *r; - n = soap_strtoll(s, &r, 10); -#else -# ifdef HAVE_SSCANF - sscanf(s, SOAP_LONG_FORMAT, &n); -# endif -#endif - return n; -} - -static bool is_integer(const char *s) -{ if ((*s == '-' || *s == '+') && s[1]) - s++; - if (!*s || strlen(s) > 20) - return false; - while (*s && isdigit(*s)) - s++; - return *s == '\0'; -} - -static void documentation(const char *text) -{ const char *s = text; - bool flag = true; - if (!s) - return; - while (*s) - { switch (*s) - { case '\n': - case '\t': - case ' ': - flag = true; - break; - default: - if (*s > 32) - { if (flag) - { fputc(' ', stream); - flag = false; - } - fputc(*s, stream); - } - } - s++; - } - fputc('\n', stream); -} - -static void operations(const char *t) -{ if (!cflag) - fprintf(stream, "/// class %s operations:\n/// - soap_new_%s(soap*) allocate\n/// - soap_new_%s(soap*, int num) allocate array\n/// - soap_new_req_%s(soap*, ...) allocate, set required members\n/// - soap_new_set_%s(soap*, ...) allocate, set all public members\n/// - int soap_read_%s(soap*, %s*) deserialize from a stream\n/// - int soap_write_%s(soap, %s*) serialize to a stream\n", t, t, t, t, t, t, t, t, t); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Allocation -// -//////////////////////////////////////////////////////////////////////////////// - -void *emalloc(size_t size) -{ void *p = malloc(size); - if (!p) - { fprintf(stderr, "\nError: Malloc failed\n"); - exit(1); - } - return p; -} - -char *estrdup(const char *s) -{ char *t = (char*)emalloc(strlen(s) + 1); - strcpy(t, s); - return t; -} - -char *estrdupf(const char *s) -{ char *t = (char*)emalloc(strlen(s) + 1); - char *p; - for (p = t; *s; s++) - { if (s[0] == '/' && s[1] == '*') - { for (s += 2; s[0] && s[1]; s++) - { if (s[0] == '*' && s[1] == '/') - { s++; - break; - } - } - continue; - } - *p++ = *s; - } - *p = '\0'; - return t; -}