1/*
2	symbol2.c
3
4	Symbol table handling, type graph handling, and code generation.
5
6--------------------------------------------------------------------------------
7gSOAP XML Web services tools
8Copyright (C) 2000-2008, Robert van Engelen, Genivia Inc. All Rights Reserved.
9This part of the software is released under ONE of the following licenses:
10GPL, the gSOAP public license, OR Genivia's license for commercial use.
11--------------------------------------------------------------------------------
12gSOAP public license.
13
14The contents of this file are subject to the gSOAP Public License Version 1.3
15(the "License"); you may not use this file except in compliance with the
16License. You may obtain a copy of the License at
17http://www.cs.fsu.edu/~engelen/soaplicense.html
18Software distributed under the License is distributed on an "AS IS" basis,
19WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20for the specific language governing rights and limitations under the License.
21
22The Initial Developer of the Original Code is Robert A. van Engelen.
23Copyright (C) 2000-2008, Robert van Engelen, Genivia Inc. All Rights Reserved.
24--------------------------------------------------------------------------------
25GPL license.
26
27This program is free software; you can redistribute it and/or modify it under
28the terms of the GNU General Public License as published by the Free Software
29Foundation; either version 2 of the License, or (at your option) any later
30version.
31
32This program is distributed in the hope that it will be useful, but WITHOUT ANY
33WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
34PARTICULAR PURPOSE. See the GNU General Public License for more details.
35
36You should have received a copy of the GNU General Public License along with
37this program; if not, write to the Free Software Foundation, Inc., 59 Temple
38Place, Suite 330, Boston, MA 02111-1307 USA
39
40Author contact information:
41engelen@genivia.com / engelen@acm.org
42
43This program is released under the GPL with the additional exemption that
44compiling, linking, and/or using OpenSSL is allowed.
45--------------------------------------------------------------------------------
46A commercial use license is available from Genivia, Inc., contact@genivia.com
47--------------------------------------------------------------------------------
48*/
49
50#include "soapcpp2.h"
51
52#ifdef HAVE_CONFIG_H
53#include "soapcpp2_yacc.h"
54#else
55#include "soapcpp2_yacc.tab.h"
56#endif
57
58char *envURI = "http://schemas.xmlsoap.org/soap/envelope/";
59char *encURI = "http://schemas.xmlsoap.org/soap/encoding/";
60char *rpcURI = "http://www.w3.org/2003/05/soap-rpc";
61char *xsiURI = "http://www.w3.org/2001/XMLSchema-instance";
62char *xsdURI = "http://www.w3.org/2001/XMLSchema";
63char *tmpURI = "http://tempuri.org";
64
65static	Symbol *symlist = (Symbol*) 0;	/* pointer to linked list of symbols */
66static	Symbol *nslist = (Symbol*) 0;	/* pointer to linked list of namespace prefix symbols */
67
68static Tnode *Tptr[TYPES];
69
70Service *services = NULL;
71
72FILE *fout, *fhead, *fclient, *fserver, *fheader, *flib, *fmatlab, *fmheader;
73
74int typeNO = 1;	/* unique no. assigned to all types */
75
76static int is_anytype_flag = 0; /* anytype is used */
77static int has_nsmap = 0;
78
79int tagcmp(const char *s, const char *t);
80
81int is_soap12(const char*);
82int has_detail_string();
83int has_Detail_string();
84
85void needs_lang(Entry *e);
86
87int is_mutable(Tnode *typ);
88int is_header_or_fault(Tnode *typ);
89int is_body(Tnode *typ);
90int is_volatile(Tnode* typ);
91int is_untyped(Tnode* typ);
92int is_primclass(Tnode* typ);
93int is_imported(Tnode* typ);
94int is_template(Tnode* typ);
95int is_mask(Tnode* typ);
96int is_attachment(Tnode* typ);
97int is_void(Tnode* typ);
98int has_external(Tnode *typ);
99int has_volatile(Tnode *typ);
100
101int is_invisible(const char *name);
102
103int is_eq_nons(const char *s, const char *t);
104int is_eq(const char *s, const char *t);
105
106int is_item(Entry *p);
107
108const char *cstring(const char*);
109
110/*
111install - add new symbol
112*/
113Symbol *
114install(const char *name, Token token)
115{ Symbol *p;
116  p = (Symbol*)emalloc(sizeof(Symbol));
117  p->name = emalloc(strlen(name)+1);
118  strcpy(p->name, name);
119  p->token = token;
120  p->next = symlist;
121  symlist = p;
122  return p;
123}
124
125/*
126lookup - search for an identifier's name. If found, return pointer to symbol table entry. Return pointer 0 if not found.
127*/
128Symbol *
129lookup(const char *name)
130{ Symbol *p;
131  for (p = symlist; p; p = p->next)
132    if (!strcmp(p->name, name))
133      return p;
134  return NULL;
135}
136
137/*
138gensymidx - generate new symbol from base name and index
139*/
140Symbol *
141gensymidx(const char *base, int idx)
142{ char buf[1024];
143  Symbol *s;
144  sprintf(buf, "%s_%d", base, idx);
145  s = lookup(buf);
146  if (s)
147    return s;
148  return install(buf, ID);
149}
150
151/*
152gensym - generate new symbol from base name
153*/
154Symbol *
155gensym(const char *base)
156{ static int num = 1;
157  return gensymidx(base, num++);
158}
159
160/*
161mktable - make a new symbol table with a pointer to a previous table
162*/
163Table *
164mktable(Table *table)
165{	Table	*p;
166	p = (Table*)emalloc(sizeof(Table));
167	p->sym = lookup("/*?*/");
168	p->list = (Entry*) 0;
169	if (table == (Table*) 0)
170		p->level = INTERNAL;
171	else	p->level = table->level+1;
172	p->prev = table;
173	return p;
174}
175
176/*
177mkmethod - make a new method by calling mktype
178*/
179Tnode *
180mkmethod(Tnode *ret, Table *args)
181{	FNinfo *fn = (FNinfo*)emalloc(sizeof(FNinfo));
182	fn->ret = ret;
183	fn->args = args;
184	return mktype(Tfun, fn, 0);
185}
186
187/*
188freetable - free space by removing a table
189*/
190void
191freetable(Table *table)
192{	Entry	*p, *q;
193	if (table == (Table*) 0)
194		return;
195	for (p = table->list; p != (Entry*) 0; p = q) {
196		q = p->next;
197		free(p);
198	}
199	free(table);
200}
201
202/*
203unlinklast - unlink last entry added to table
204*/
205Entry *
206unlinklast(Table *table)
207{	Entry	**p, *q;
208	if (table == (Table*)0)
209		return (Entry*)0;
210	for (p = &table->list; *p != (Entry*)0 && (*p)->next != (Entry*)0;
211	     p = &(*p)->next);
212	q = *p;
213	*p = (Entry*)0;
214	return q;
215}
216
217/*
218enter - enter a symbol in a table. Error if already in the table
219*/
220Entry *
221enter(Table *table, Symbol *sym)
222{ Entry	*p, *q = NULL;
223  for (p = table->list; p; q = p, p = p->next)
224  { if (p->sym == sym && p->info.typ->type != Tfun)
225    { sprintf(errbuf, "Duplicate declaration of %s (already declarared at line %d)", sym->name, p->lineno);
226      semerror(errbuf);
227      return p;
228    }
229  }
230  p = (Entry*)emalloc(sizeof(Entry));
231  p->sym = sym;
232  p->info.typ = NULL;
233  p->info.sto = Snone;
234  p->info.hasval = False;
235  p->info.minOccurs = 1;
236  p->info.maxOccurs = 1;
237  p->info.offset = 0;
238  p->level = table->level;
239  p->lineno = yylineno;
240  p->next = NULL;
241  if (!q)
242    table->list = p;
243  else
244    q->next = p;
245  return p;
246}
247
248/*
249entry - return pointer to table entry of a symbol
250*/
251Entry *
252entry(Table *table, Symbol *sym)
253{ Table	*t;
254  Entry	*p;
255  for (t = table; t; t = t->prev)
256    for (p = t->list; p; p = p->next)
257      if (p->sym == sym)
258	return p;
259  return NULL;
260}
261
262/*
263reenter - re-enter a symbol in a table.
264*/
265Entry *
266reenter(Table *table, Symbol *sym)
267{ Entry	*p, *q = NULL;
268  for (p = table->list; p; q = p, p = p->next)
269    if (p->sym == sym)
270      break;
271  if (p && p->next)
272  { if (q)
273      q->next = p->next;
274    else
275      table->list = p->next;
276    for (q = p->next; q->next; q = q->next)
277      ;
278    q->next = p;
279    p->next = NULL;
280  }
281  return p;
282}
283
284/*
285merge - append two tables if members are not duplicated
286*/
287int
288merge(Table *dest, Table *src)
289{ Entry *p, *q;
290  for (p = src->list; p; p = p->next)
291  { q = entry(dest, p->sym);
292    if (!q || q->info.typ != p->info.typ)
293    { q = enter(dest, p->sym);
294      q->info = p->info;
295    }
296  }
297  return 0;
298}
299
300Entry *
301enumentry(Symbol *sym)
302{ Table	*t;
303  Entry	*p, *q;
304  for (t = enumtable; t; t = t->prev)
305  { for (p = t->list; p; p = p->next)
306    { q = entry(p->info.typ->ref, sym);
307      if (q)
308	return q;
309    }
310  }
311  return NULL;
312}
313
314char *get_mxClassID(Tnode*);
315char *t_ident(Tnode*);
316char *c_ident(Tnode*);
317char *ident(char*);
318char *soap_type(Tnode*);
319char *c_storage(Storage);
320char *c_init(Entry*);
321char *c_type(Tnode*);
322char *c_type_id(Tnode*, char*);
323char *xsi_type_cond(Tnode*, int);
324char *xsi_type(Tnode*);
325char *xsi_type_cond_u(Tnode*, int);
326char *xsi_type_u(Tnode*);
327char *the_type(Tnode*);
328char *wsdl_type(Tnode*, char*);
329char *base_type(Tnode*, char*);
330char *xml_tag(Tnode*);
331char *ns_qualifiedElement(Tnode*);
332char *ns_qualifiedAttribute(Tnode*);
333char *ns_convert(char*);
334char *ns_add(char*, char*);
335char *ns_remove(char*);
336char *ns_remove1(char*);
337char *ns_remove2(char*);
338char *res_remove(char*);
339char *ns_name(char*);
340char *ns_cname(char*, char*);
341
342int has_class(Tnode*);
343int has_constructor(Tnode*);
344int has_destructor(Tnode*);
345int has_getter(Tnode*);
346int has_setter(Tnode*);
347int has_ns(Tnode*);
348int has_ns_t(Tnode*);
349int has_ns_eq(char*, char*);
350char *strict_check();
351char *ns_of(char*);
352char *prefix_of(char*);
353int has_offset(Tnode*);
354int reflevel(Tnode *typ);
355Tnode* reftype(Tnode *typ);
356int is_response(Tnode*);
357int is_XML(Tnode*);
358Entry *get_response(Tnode*);
359int is_primitive_or_string(Tnode*);
360int is_primitive(Tnode*);
361Entry *is_discriminant(Tnode*);
362Entry *is_dynamic_array(Tnode*);
363int is_transient(Tnode*);
364int is_external(Tnode*);
365int is_anyType(Tnode*);
366int is_anyAttribute(Tnode*);
367int is_binary(Tnode*);
368int is_hexBinary(Tnode*);
369int is_string(Tnode*);
370int is_wstring(Tnode*);
371int is_stdstring(Tnode*);
372int is_stdwstring(Tnode*);
373int is_stdstr(Tnode*);
374int is_typedef(Tnode*);
375int get_dimension(Tnode*);
376char *has_soapref(Tnode*);
377int is_document(const char*);
378int is_literal(const char*);
379int is_keyword(const char *);
380
381int is_repetition(Entry*);
382int is_choice(Entry*);
383int is_sequence(Entry*);
384int is_anytype(Entry*);
385
386char *xsi_type_Tarray(Tnode*);
387char *xsi_type_Darray(Tnode*);
388
389void matlab_def_table(Table*);
390void def_table(Table*);
391void out_generate(Tnode *);
392int no_of_var(Tnode*);
393char *pointer_stuff(Tnode*);
394void in_defs(Table*);
395void in_defs2(Table*);
396void in_defs3(Table*);
397void out_defs(Table*);
398void mark_defs(Table*);
399void in_attach(Table*);
400void out_attach(Table*);
401void mark(Tnode*);
402void defaults(Tnode*);
403void soap_put(Tnode*);
404void soap_out(Tnode*);
405void soap_out_Darray(Tnode *);
406void soap_get(Tnode*);
407void soap_in(Tnode*);
408void soap_in_Darray(Tnode *);
409void soap_instantiate_class(Tnode *);
410int get_Darraydims(Tnode *typ);
411
412void soap_serve(Table*);
413void generate_proto(Table*, Entry*);
414/*
415void generate_call(Table*, Entry*);
416void generate_server(Table*, Entry*);
417*/
418void generate_header(Table*);
419void generate_schema(Table*);
420void gen_schema(FILE*,Table*,char*,char*,int,int,char*,char*,char*,char*);
421void gen_type_documentation(FILE *fd, Table *t, Entry *p, char *ns, char *ns1);
422void gen_schema_elements_attributes(FILE *fd, Table *t, char *ns, char *ns1, char *encoding, char *style);
423void gen_schema_elements(FILE *fd, Tnode *p, char *ns, char *ns1);
424int gen_schema_element(FILE *fd, Entry *q, char *ns, char *ns1);
425void gen_schema_attributes(FILE *fd, Tnode *p, char *ns, char *ns1);
426void gen_wsdl(FILE*,Table*,char*,char*,char*,char*,char*,char*,char*);
427void gen_nsmap(FILE*,Symbol*,char*);
428
429void gen_proxy(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
430void gen_object(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
431void gen_proxy_header(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
432void gen_proxy_code(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
433void gen_object_header(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
434void gen_object_code(FILE*,Table*,Symbol*,char*,char*,char*,char*,char*);
435void gen_method(FILE *fd, Table *table, Entry *method, int server);
436void gen_params(FILE *fd, Table *params, Entry *result, int flag);
437void gen_args(FILE *fd, Table *params, Entry *result, int flag);
438void gen_call_method(FILE *fd, Table *table, Entry *method, char *name);
439void gen_serve_method(FILE *fd, Table *table, Entry *param, char *name);
440
441void gen_data(char*,Table*,char*,char*,char*,char*,char*,char*);
442FILE *gen_env(char*,char*,int,Table*,char*,char*,char*,char*,char*,char*);
443void gen_field(FILE*,int,Entry*,char*,char*,char*);
444void gen_val(FILE*,int,Tnode*,char*,char*,char*);
445void gen_atts(FILE*,Table*,char*);
446
447/*
448mktype - make a (new) type with a reference to additional information and the
449width in bytes required to store objects of that type. A pointer to the
450type is returned which can be compared to check if types are identical.
451*/
452Tnode *
453mktype(Type type, void *ref, int width)
454{	Tnode	*p;
455	int t = 0;
456	if (transient != -2 || type > Ttime)
457	  t = transient;
458	if (type != Tstruct && type != Tclass && type != Tunion && (type != Tenum || ref))
459	{	for (p = Tptr[type]; p; p = p->next)
460		{	if (p->ref == ref && p->sym == (Symbol*) 0 && p->width == width && p->transient == t)
461			{	if (imported && !p->imported)
462					p->imported = imported;
463				return p;	/* type alrady exists in table */
464			}
465		}
466	}
467	p = (Tnode*)emalloc(sizeof(Tnode));	/* install new type */
468	p->type = type;
469	p->ref = ref;
470	p->id = lookup("/*?*/");
471	p->base = NULL;
472	p->sym = (Symbol*)0;
473	p->response = (Entry*)0;
474	p->width = width;
475	p->generated = False;
476	p->wsdl = False;
477	p->next = Tptr[type];
478	p->transient = t;
479	p->imported = imported;
480	p->pattern = NULL;
481	p->minLength = -1;
482	p->maxLength = -1;
483	p->num = typeNO++;
484	Tptr[type] = p;
485	DBGLOG(fprintf(stderr, "New type %s %s\n", c_type(p), p->imported));
486	if (type == Tpointer && ((Tnode*)ref)->imported && (((Tnode*)ref)->type == Tenum || ((Tnode*)ref)->type == Tstruct || ((Tnode*)ref)->type == Tclass))
487	  p->imported = ((Tnode*)ref)->imported;
488	else if (lflag && !is_transient(p) && (type == Tenum || type == Tstruct || type == Tclass))
489	  mkpointer(p);
490	return p;
491}
492
493Tnode *
494mksymtype(Tnode *typ, Symbol *sym)
495{	Tnode *p;
496	p = (Tnode*)emalloc(sizeof(Tnode));	/* install new type */
497	p->type = typ->type;
498	p->ref = typ->ref;
499	p->id = typ->id;
500	p->sym = sym;
501	p->response = (Entry*)0;
502	p->width = typ->width;
503	p->generated = True; /* copy of existing (generated) type */
504	p->wsdl = False;
505	p->next = Tptr[typ->type];
506	p->transient = transient;
507	p->imported = imported;
508	p->pattern = NULL;
509	p->minLength = -1;
510	p->maxLength = -1;
511	p->num = typeNO++;
512	Tptr[typ->type] = p;
513	DBGLOG(fprintf(stderr, "New typedef %s %s\n", c_type(p), p->imported));
514	return p;
515}
516
517Tnode *
518mktemplate(Tnode *typ, Symbol *id)
519{	Tnode *p;
520	for (p = Tptr[Ttemplate]; p; p = p->next)
521		if (p->ref == typ && p->id == id && p->transient == transient)
522		{	if (imported && !p->imported)
523				p->imported = imported;
524			return p;	/* type alrady exists in table */
525		}
526	p = (Tnode*)emalloc(sizeof(Tnode));	/* install new type */
527	p->type = Ttemplate;
528	p->ref = typ;
529	p->id = id;
530	p->sym = NULL;
531	p->response = (Entry*)0;
532	p->width = 0;
533	p->generated = False; /* copy of existing (generated) type */
534	p->wsdl = False;
535	p->next = Tptr[Ttemplate];
536	p->transient = transient;
537	p->imported = imported;
538	p->pattern = NULL;
539	p->minLength = -1;
540	p->maxLength = -1;
541	p->num = typeNO++;
542	Tptr[Ttemplate] = p;
543	return p;
544}
545
546/*	DO NOT REMOVE OR ALTER (SEE LICENCE AGREEMENT AND COPYING.txt)	*/
547void
548copyrightnote(FILE *fd, char *fn)
549{ fprintf(fd, "/* %s\n   Generated by gSOAP "VERSION" from %s\n   Copyright(C) 2000-2008, Robert van Engelen, Genivia Inc. All Rights Reserved.\n   This part of the software is released under one of the following licenses:\n   GPL, the gSOAP public license, or Genivia's license for commercial use.\n*/", fn, filename);
550}
551
552void
553banner(FILE *fd, const char *text)
554{ int i;
555  fprintf(fd, "\n\n/");
556  for (i = 0; i < 78; i++)
557    fputc('*', fd);
558  fprintf(fd, "\\\n *%76s*\n * %-75s*\n *%76s*\n\\", "", text, "");
559  for (i = 0; i < 78; i++)
560    fputc('*', fd);
561  fprintf(fd, "/\n");
562}
563
564void
565identify(FILE *fd, char *fn)
566{ time_t t = time(NULL), *p = &t;
567  char tmp[256];
568  strftime(tmp, 256, "%Y-%m-%d %H:%M:%S GMT", gmtime(p));
569  fprintf(fd, "\n\nSOAP_SOURCE_STAMP(\"@(#) %s ver "VERSION" %s\")\n", fn, tmp);
570}
571
572void
573compile(Table *table)
574{	Entry *p;
575	Tnode *typ;
576	Pragma *pragma;
577	int classflag = 0;
578	char *s;
579	char base[1024];
580	char soapStub[1024];
581	char soapH[1024];
582	char soapC[1024];
583	char soapClient[1024];
584	char soapServer[1024];
585	char soapClientLib[1024];
586	char soapServerLib[1024];
587	char pathsoapStub[1024];
588	char pathsoapH[1024];
589	char pathsoapC[1024];
590	char pathsoapClient[1024];
591	char pathsoapServer[1024];
592	char pathsoapClientLib[1024];
593	char pathsoapServerLib[1024];
594      	char soapMatlab[1024];
595      	char pathsoapMatlab[1024];
596  	char soapMatlabHdr[1024];
597      	char pathsoapMatlabHdr[1024];
598
599	if (*dirpath)
600	  fprintf(fmsg, "Using project directory path: %s\n", dirpath);
601
602	if (namespaceid)
603	{ prefix = namespaceid;
604	  fprintf(fmsg, "Using code namespace: %s\n", namespaceid);
605	}
606	strcpy(base, prefix);
607	if (cflag)
608		s = ".c";
609	else
610		s = ".cpp";
611
612  	strcpy(soapMatlab, base);
613  	strcat(soapMatlab, "Matlab.c");
614  	strcpy(pathsoapMatlab, dirpath);
615  	strcat(pathsoapMatlab, soapMatlab );
616
617  	strcpy(soapMatlabHdr, base);
618  	strcat(soapMatlabHdr, "Matlab.h");
619  	strcpy(pathsoapMatlabHdr, dirpath);
620  	strcat(pathsoapMatlabHdr, soapMatlabHdr);
621
622	strcpy(soapStub, base);
623	strcat(soapStub, "Stub.h");
624	strcpy(pathsoapStub, dirpath);
625	strcat(pathsoapStub, soapStub);
626	strcpy(soapH, base);
627	strcat(soapH, "H.h");
628	strcpy(pathsoapH, dirpath);
629	strcat(pathsoapH, soapH);
630	strcpy(soapC, base);
631	strcat(soapC, "C");
632	strcat(soapC, s);
633	strcpy(pathsoapC, dirpath);
634	strcat(pathsoapC, soapC);
635	strcpy(soapClient, base);
636	strcat(soapClient, "Client");
637	strcat(soapClient, s);
638	strcpy(pathsoapClient, dirpath);
639	strcat(pathsoapClient, soapClient);
640	strcpy(soapServer, base);
641	strcat(soapServer, "Server");
642	strcat(soapServer, s);
643	strcpy(pathsoapServer, dirpath);
644	strcat(pathsoapServer, soapServer);
645	strcpy(soapClientLib, base);
646	strcat(soapClientLib, "ClientLib");
647	strcat(soapClientLib, s);
648	strcpy(pathsoapClientLib, dirpath);
649	strcat(pathsoapClientLib, soapClientLib);
650	strcpy(soapServerLib, base);
651	strcat(soapServerLib, "ServerLib");
652	strcat(soapServerLib, s);
653	strcpy(pathsoapServerLib, dirpath);
654	strcat(pathsoapServerLib, soapServerLib);
655
656	if (mflag)
657 	{ fprintf(fmsg, "Saving %s\n", pathsoapMatlab);
658 	  fmatlab=fopen(pathsoapMatlab, "w");
659 	  if (!fmatlab)
660 		execerror("Cannot write to file");
661 	  copyrightnote(fmatlab, soapMatlab);
662 	  fprintf(fmatlab,"\n#include \"%s\"\n", soapMatlabHdr);
663 	  fprintf(fmsg, "Saving %s\n", pathsoapMatlabHdr);
664 	  fmheader=fopen(pathsoapMatlabHdr, "w");
665 	  if (!fmheader)
666		execerror("Cannot write to file");
667 	  copyrightnote(fmheader, soapMatlabHdr);
668 	  fprintf(fmheader,"\n#include \"mex.h\"\n#include \"%s\"\n", soapStub);
669	}
670
671	fprintf(fmsg, "Saving %s\n", pathsoapStub);
672	fheader=fopen(pathsoapStub, "w");
673	if (!fheader)
674		execerror("Cannot write to file");
675	copyrightnote(fheader, soapStub);
676	fprintf(fmsg, "Saving %s\n", pathsoapH);
677	fhead=fopen(pathsoapH,"w");
678	if (!fhead)
679		execerror("Cannot write to file");
680	copyrightnote(fhead, soapH);
681	fprintf(fmsg, "Saving %s\n", pathsoapC);
682	fout=fopen(pathsoapC,"w");
683	if (!fout)
684		execerror("Cannot write to file");
685	copyrightnote(fout, soapC);
686	if (!Sflag && !iflag)
687	{ fprintf(fmsg, "Saving %s\n", pathsoapClient);
688          fclient=fopen(pathsoapClient,"w");
689	  if (!fclient)
690		execerror("Cannot write to file");
691	  copyrightnote(fclient, soapClient);
692          fprintf(fclient,"\n#include \"%sH.h\"", prefix);
693	  if (cflag)
694	    fprintf(fclient,"\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
695          if (namespaceid)
696            fprintf(fclient,"\n\nnamespace %s {", namespaceid);
697	  identify(fclient, soapClient);
698
699	  if (!Lflag)
700	  { flib=fopen(pathsoapClientLib,"w");
701	    if (!flib)
702		execerror("Cannot write to file");
703	    copyrightnote(flib, soapClientLib);
704	    fprintf(fmsg, "Saving %s\n", pathsoapClientLib);
705	    fprintf(flib, "\n#ifndef WITH_NOGLOBAL\n#define WITH_NOGLOBAL\n#endif");
706	    fprintf(flib, "\n#define SOAP_FMAC3 static");
707	    fprintf(flib, "\n#include \"%s\"", soapC);
708	    fprintf(flib, "\n#include \"%s\"", soapClient);
709	    fprintf(flib, "\n\n/* End of %s */\n", soapClientLib);
710	    fclose(flib);
711	  }
712	}
713	if (!Cflag && !iflag)
714	{ fprintf(fmsg, "Saving %s\n", pathsoapServer);
715          fserver=fopen(pathsoapServer,"w");
716	  if (!fserver)
717		execerror("Cannot write to file");
718	  copyrightnote(fserver, soapServer);
719          fprintf(fserver,"\n#include \"%sH.h\"", prefix);
720	  if (cflag)
721	    fprintf(fserver,"\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
722          if (namespaceid)
723            fprintf(fserver,"\n\nnamespace %s {", namespaceid);
724	  identify(fserver, soapServer);
725
726	  if (!Lflag)
727	  { flib=fopen(pathsoapServerLib,"w");
728	    if (!flib)
729		execerror("Cannot write to file");
730	    copyrightnote(flib, soapServerLib);
731	    fprintf(fmsg, "Saving %s\n", pathsoapServerLib);
732	    fprintf(flib, "\n#ifndef WITH_NOGLOBAL\n#define WITH_NOGLOBAL\n#endif");
733	    fprintf(flib, "\n#define SOAP_FMAC3 static");
734	    fprintf(flib, "\n#include \"%s\"", soapC);
735	    fprintf(flib, "\n#include \"%s\"", soapServer);
736	    fprintf(flib, "\n\n/* End of %s */\n", soapServerLib);
737	    fclose(flib);
738	  }
739	}
740
741	fprintf(fhead,"\n\n#ifndef %sH_H\n#define %sH_H", prefix, prefix);
742	fprintf(fhead,"\n#include \"%s\"", soapStub);
743	if (cflag)
744	  fprintf(fhead,"\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
745	if (namespaceid)
746	  fprintf(fhead,"\n\nnamespace %s {", namespaceid);
747	fprintf(fheader,"\n\n#ifndef %sStub_H\n#define %sStub_H", prefix, prefix);
748	for (pragma = pragmas; pragma; pragma = pragma->next)
749	  fprintf(fheader,"\n%s", pragma->pragma);
750	if (nflag)
751	  fprintf(fheader,"\n#ifndef WITH_NONAMESPACES\n#define WITH_NONAMESPACES\n#endif");
752	if (namespaceid)
753	{ fprintf(fheader,"\n#ifndef WITH_NOGLOBAL\n#define WITH_NOGLOBAL\n#endif");
754	}
755	fprintf(fheader,"\n#include \"stdsoap2.h\"");
756	if (cflag)
757	  fprintf(fheader,"\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
758	if (namespaceid)
759	  fprintf(fheader,"\n\nnamespace %s {", namespaceid);
760	generate_header(table);
761	generate_schema(table);
762	fprintf(fout,"\n\n#include \"%sH.h\"", prefix);
763	if (cflag)
764	  fprintf(fout,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
765	if (namespaceid)
766	  fprintf(fout,"\n\nnamespace %s {", namespaceid);
767	identify(fout, soapC);
768
769        if (!iflag)
770	  soap_serve(table);
771
772	fprintf(fhead, "\n#ifndef WITH_NOIDREF");
773	if (!cflag && !namespaceid)
774	  fprintf(fhead,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
775	fprintf(fhead, "\nSOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap*, const void*, int);");
776	fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap*, const void*, const char*, int, int);");
777	fprintf(fhead, "\nSOAP_FMAC3 void *SOAP_FMAC4 soap_getelement(struct soap*, int*);");
778	if (!cflag && !namespaceid)
779	  fprintf(fhead,"\n\n#ifdef __cplusplus\n}\n#endif");
780	fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_putindependent(struct soap*);");
781	fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_getindependent(struct soap*);");
782	fprintf(fhead, "\n#endif");
783	fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap*);");
784	if (!lflag)
785	{
786	fprintf(fout,"\n\n#ifndef WITH_NOGLOBAL");
787        if ((p = entry(classtable, lookup("SOAP_ENV__Header"))) && p->info.typ->type == Tstruct)
788	  fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serializeheader(struct soap *soap)\n{\n\tif (soap->header)\n\t\tsoap_serialize_SOAP_ENV__Header(soap, soap->header);\n}");
789	else
790	  fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serializeheader(struct soap *soap)\n{\n\tif (soap->header)\n\t\tsoap->header->soap_serialize(soap);\n}");
791	fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_putheader(struct soap *soap)\n{\n\tif (soap->header)\n\t{\tsoap->part = SOAP_IN_HEADER;\n\t\tif (soap_out_SOAP_ENV__Header(soap, \"SOAP-ENV:Header\", 0, soap->header, NULL))\n\t\t\treturn soap->error;\n\t\tsoap->part = SOAP_END_HEADER;\n\t}\n\treturn SOAP_OK;\n}");
792	fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_getheader(struct soap *soap)\n{\n\tsoap->part = SOAP_IN_HEADER;\n\tsoap->header = soap_in_SOAP_ENV__Header(soap, \"SOAP-ENV:Header\", NULL, NULL);\n\tsoap->part = SOAP_END_HEADER;\n\treturn soap->header == NULL;\n}");
793        if (cflag)
794	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap)\n{\n\tif (!soap->header)\n\t{\tsoap->header = (struct SOAP_ENV__Header*)soap_malloc(soap, sizeof(struct SOAP_ENV__Header));\n\t\tsoap_default_SOAP_ENV__Header(soap, soap->header);\n\t}\n}");
795	}
796        else if ((p = entry(classtable, lookup("SOAP_ENV__Fault"))) && p->info.typ->type == Tstruct)
797	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap)\n{\n\tif (!soap->header)\n\t{\tsoap->header = soap_new_SOAP_ENV__Header(soap, -1);\n\t\tsoap_default_SOAP_ENV__Header(soap, soap->header);\n\t}\n}");
798	}
799	else
800	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap)\n{\n\tif (!soap->header)\n\t{\tsoap->header = soap_new_SOAP_ENV__Header(soap, -1);\n\t\tsoap->header->soap_default(soap);\n\t}\n}");
801	}
802        if (cflag)
803	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_fault(struct soap *soap)\n{\n\tif (!soap->fault)\n\t{\tsoap->fault = (struct SOAP_ENV__Fault*)soap_malloc(soap, sizeof(struct SOAP_ENV__Fault));\n\t\tif (!soap->fault)\n\t\t\treturn;\n\t\tsoap_default_SOAP_ENV__Fault(soap, soap->fault);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Code)\n\t{\tsoap->fault->SOAP_ENV__Code = (struct SOAP_ENV__Code*)soap_malloc(soap, sizeof(struct SOAP_ENV__Code));\n\t\tsoap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Reason)\n\t{\tsoap->fault->SOAP_ENV__Reason = (struct SOAP_ENV__Reason*)soap_malloc(soap, sizeof(struct SOAP_ENV__Reason));\n\t\tsoap_default_SOAP_ENV__Reason(soap, soap->fault->SOAP_ENV__Reason);\n\t}\n}");
804	  fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serializefault(struct soap *soap)\n{\n\tif (soap->fault)\n\t\tsoap_serialize_SOAP_ENV__Fault(soap, soap->fault);\n}");
805	}
806        else if ((p = entry(classtable, lookup("SOAP_ENV__Fault"))) && p->info.typ->type == Tstruct)
807	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_fault(struct soap *soap)\n{\n\tif (!soap->fault)\n\t{\tsoap->fault = soap_new_SOAP_ENV__Fault(soap, -1);\n\t\tif (!soap->fault)\n\t\t\treturn;\n\t\tsoap_default_SOAP_ENV__Fault(soap, soap->fault);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Code)\n\t{\tsoap->fault->SOAP_ENV__Code = soap_new_SOAP_ENV__Code(soap, -1);\n\t\tsoap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Reason)\n\t{\tsoap->fault->SOAP_ENV__Reason = soap_new_SOAP_ENV__Reason(soap, -1);\n\t\tsoap_default_SOAP_ENV__Reason(soap, soap->fault->SOAP_ENV__Reason);\n\t}\n}");
808	  fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serializefault(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->fault)\n\t\tsoap_serialize_SOAP_ENV__Fault(soap, soap->fault);\n}");
809	}
810	else
811	{ fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_fault(struct soap *soap)\n{\n\tif (!soap->fault)\n\t{\tsoap->fault = soap_new_SOAP_ENV__Fault(soap, -1);\n\t\tsoap->fault->soap_default(soap);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Code)\n\t{\tsoap->fault->SOAP_ENV__Code = soap_new_SOAP_ENV__Code(soap, -1);\n\t\tsoap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code);\n\t}\n\tif (soap->version == 2 && !soap->fault->SOAP_ENV__Reason)\n\t{\tsoap->fault->SOAP_ENV__Reason = soap_new_SOAP_ENV__Reason(soap, -1);\n\t\tsoap_default_SOAP_ENV__Reason(soap, soap->fault->SOAP_ENV__Reason);\n\t}\n}");
812	  fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serializefault(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->fault)\n\t\tsoap->fault->soap_serialize(soap);\n}");
813	}
814        if ((p = entry(classtable, lookup("SOAP_ENV__Fault"))) && p->info.typ->type == Tstruct)
815	{ fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_putfault(struct soap *soap)\n{\n\tif (soap->fault)\n\t\treturn soap_put_SOAP_ENV__Fault(soap, soap->fault, \"SOAP-ENV:Fault\", NULL);\n\treturn SOAP_OK;\n}");
816	  fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_getfault(struct soap *soap)\n{\n\treturn (soap->fault = soap_get_SOAP_ENV__Fault(soap, NULL, \"SOAP-ENV:Fault\", NULL)) == NULL;\n}");
817	}
818	else
819	{ fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_putfault(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->fault)\n\t\treturn soap->fault->soap_put(soap, \"SOAP-ENV:Fault\", NULL);\n\treturn SOAP_EOM;\n}");
820	  fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_getfault(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->fault)\n\t\treturn soap->fault->soap_get(soap, \"SOAP-ENV:Fault\", NULL) == NULL;\n\treturn SOAP_EOM;\n}");
821	}
822	fprintf(fout,"\n\nSOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultcode(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->version == 2)\n\t\treturn (const char**)&soap->fault->SOAP_ENV__Code->SOAP_ENV__Value;\n\treturn (const char**)&soap->fault->faultcode;\n}");
823	if (cflag)
824	  fprintf(fout,"\n\nSOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultsubcode(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->version == 2)\n\t{\tif (!soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode)\n\t\t{\tsoap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode = (struct SOAP_ENV__Code*)soap_malloc(soap, sizeof(struct SOAP_ENV__Code));\n\t\t\tsoap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode);\n\t\t}\n\t\treturn (const char**)&soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode->SOAP_ENV__Value;\n\t}\n\treturn (const char**)&soap->fault->faultcode;\n}");
825        else
826	  fprintf(fout,"\n\nSOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultsubcode(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->version == 2)\n\t{\tif (!soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode)\n\t\t{\tsoap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode = soap_new_SOAP_ENV__Code(soap, -1);\n\t\t\tsoap_default_SOAP_ENV__Code(soap, soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode);\n\t\t}\n\t\treturn (const char**)&soap->fault->SOAP_ENV__Code->SOAP_ENV__Subcode->SOAP_ENV__Value;\n\t}\n\treturn (const char**)&soap->fault->faultcode;\n}");
827	fprintf(fout,"\n\nSOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultstring(struct soap *soap)\n{\n\tsoap_fault(soap);\n\tif (soap->version == 2)\n\t\treturn (const char**)&soap->fault->SOAP_ENV__Reason->SOAP_ENV__Text;\n\treturn (const char**)&soap->fault->faultstring;\n}");
828	fprintf(fout,"\n\nSOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultdetail(struct soap *soap)\n{\n\tsoap_fault(soap);");
829	if (has_detail_string())
830	  fprintf(fout,"\n\tif (soap->version == 1)\n\t{\tif (!soap->fault->detail)\n\t\t{\tsoap->fault->detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail));\n\t\t\tsoap_default_SOAP_ENV__Detail(soap, soap->fault->detail);\n\t\t}\n\t\treturn (const char**)&soap->fault->detail->__any;\n\t}");
831	if (has_Detail_string())
832	{ if (cflag)
833	    fprintf(fout,"\n\tif (!soap->fault->SOAP_ENV__Detail)\n\t{\tsoap->fault->SOAP_ENV__Detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail));\n\t\tsoap_default_SOAP_ENV__Detail(soap, soap->fault->SOAP_ENV__Detail);\n\t}\n\treturn (const char**)&soap->fault->SOAP_ENV__Detail->__any;\n}");
834	  else
835	    fprintf(fout,"\n\tif (!soap->fault->SOAP_ENV__Detail)\n\t{\tsoap->fault->SOAP_ENV__Detail = soap_new_SOAP_ENV__Detail(soap, -1);\n\t\tsoap_default_SOAP_ENV__Detail(soap, soap->fault->SOAP_ENV__Detail);\n\t}\n\treturn (const char**)&soap->fault->SOAP_ENV__Detail->__any;\n}");
836	}
837        if (!has_detail_string() && !has_Detail_string())
838	  fprintf(fout,"\n\treturn NULL;\n}");
839	fprintf(fout,"\n\n#endif");
840
841	fprintf(fout,"\n\n#ifndef WITH_NOIDREF");
842	fprintf(fout,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_getindependent(struct soap *soap)\n{");
843	fprintf(fout,"\n\tint t;\n\tfor (;;)");
844	fprintf(fout,"\n\t\tif (!soap_getelement(soap, &t))");
845        fprintf(fout,"\n\t\t\tif (soap->error || soap_ignore_element(soap))\n\t\t\t\tbreak;");
846        fprintf(fout,"\n\tif (soap->error == SOAP_NO_TAG || soap->error == SOAP_EOF)");
847        fprintf(fout,"\n\t\tsoap->error = SOAP_OK;");
848        fprintf(fout,"\n\treturn soap->error;");
849        fprintf(fout,"\n}\n#endif");
850
851        fprintf(fout,"\n\n#ifndef WITH_NOIDREF");
852	if (!cflag && !namespaceid)
853	  fprintf(fout,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
854	fprintf(fout,"\nSOAP_FMAC3 void * SOAP_FMAC4 soap_getelement(struct soap *soap, int *type)\n{");
855        fprintf(fout,"\n\tif (soap_peek_element(soap))\n\t\treturn NULL;");
856	fprintf(fout,"\n\tif (!*soap->id || !(*type = soap_lookup_type(soap, soap->id)))\n\t\t*type = soap_lookup_type(soap, soap->href);");
857	fprintf(fout,"\n\tswitch (*type)\n\t{");
858	DBGLOG(fprintf(stderr,"\n Calling in_defs( )."));
859	fflush(fout);
860	in_defs(table);
861	DBGLOG(fprintf(stderr,"\n Completed in_defs( )."));
862        fprintf(fout,"\n\tdefault:\n\t{\tconst char *t = soap->type;\n\t\tif (!*t)\n\t\t\tt = soap->tag;");
863	fflush(fout);
864	in_defs2(table);
865        fprintf(fout,"\n\t\tt = soap->tag;");
866	in_defs3(table);
867        fprintf(fout,"\n\t}\n\t}\n\tsoap->error = SOAP_TAG_MISMATCH;\n\treturn NULL;\n}");
868	if (!cflag && !namespaceid)
869	  fprintf(fout,"\n\n#ifdef __cplusplus\n}\n#endif");
870        fprintf(fout,"\n#endif");
871
872	fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap *soap)\n{");
873	fprintf(fout,"\n\tif (!soap_peek_element(soap))");
874	fprintf(fout,"\n\t{\tint t;");
875	fprintf(fout,"\n\t\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Unexpected element '%%s' in input (level=%%u, %%d)\\n\", soap->tag, soap->level, soap->body));");
876	fprintf(fout,"\n\t\tif (soap->mustUnderstand && !soap->other)");
877	fprintf(fout,"\n\t\t\treturn soap->error = SOAP_MUSTUNDERSTAND;");
878	fprintf(fout,"\n\t\tif (((soap->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER) || !soap_match_tag(soap, soap->tag, \"SOAP-ENV:\"))\n\t\t{\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"REJECTING element '%%s'\\n\", soap->tag));\n\t\t\treturn soap->error = SOAP_TAG_MISMATCH;\n\t\t}");
879	fprintf(fout,"\n\t\tif (!*soap->id || !soap_getelement(soap, &t))");
880	fprintf(fout,"\n\t\t{\tsoap->peeked = 0;");
881	fprintf(fout,"\n\t\t\tif (soap->fignore)\n\t\t\t\tsoap->error = soap->fignore(soap, soap->tag);\n\t\t\telse\n\t\t\t\tsoap->error = SOAP_OK;");
882	fprintf(fout,"\n\t\t\tDBGLOG(TEST, if (!soap->error) SOAP_MESSAGE(fdebug, \"IGNORING element '%%s'\\n\", soap->tag));");
883	fprintf(fout,"\n\t\t\tif (!soap->error && soap->body)");
884	fprintf(fout,"\n\t\t\t{\tsoap->level++;");
885	fprintf(fout,"\n\t\t\t\twhile (!soap_ignore_element(soap))");
886	fprintf(fout,"\n\t\t\t\t\t;");
887	fprintf(fout,"\n\t\t\t\tif (soap->error == SOAP_NO_TAG)");
888	fprintf(fout,"\n\t\t\t\t\tsoap->error = soap_element_end_in(soap, NULL);");
889	fprintf(fout,"\n\t\t\t}");
890	fprintf(fout,"\n\t\t}");
891	fprintf(fout,"\n\t}");
892	fprintf(fout,"\n\treturn soap->error;");
893	fprintf(fout,"\n}");
894
895	fprintf(fout,"\n\n#ifndef WITH_NOIDREF");
896	fprintf(fout,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_putindependent(struct soap *soap)\n{\n\tint i;\n\tstruct soap_plist *pp;");
897	fprintf(fout,"\n\tif (soap->version == 1 && soap->encodingStyle && !(soap->mode & (SOAP_XML_TREE | SOAP_XML_GRAPH)))");
898	fprintf(fout,"\n\t\tfor (i = 0; i < SOAP_PTRHASH; i++)");
899	fprintf(fout,"\n\t\t\tfor (pp = soap->pht[i]; pp; pp = pp->next)");
900	fprintf(fout,"\n\t\t\t\tif (pp->mark1 == 2 || pp->mark2 == 2)");
901	fprintf(fout,"\n\t\t\t\t\tif (soap_putelement(soap, pp->ptr, \"id\", pp->id, pp->type))\n\t\t\t\t\t\treturn soap->error;");
902	fprintf(fout,"\n\treturn SOAP_OK;\n}\n#endif");
903
904	fprintf(fout,"\n\n#ifndef WITH_NOIDREF");
905	if (!cflag && !namespaceid)
906	  fprintf(fout,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
907	fprintf(fout,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap *soap, const void *ptr, const char *tag, int id, int type)\n{");
908	fprintf(fout,"\n\tswitch (type)\n\t{");
909	fflush(fout);
910        out_defs(table);
911	fprintf(fout,"\n\t}\n\treturn SOAP_OK;\n}");
912	if (!cflag && !namespaceid)
913	  fprintf(fout,"\n\n#ifdef __cplusplus\n}\n#endif");
914	fprintf(fout,"\n#endif");
915
916	fprintf(fout,"\n\n#ifndef WITH_NOIDREF");
917	if (!cflag && !namespaceid)
918	  fprintf(fout,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif");
919	if (is_anytype_flag)
920	{ fprintf(fout,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap *soap, const void *ptr, int type)\n{");
921	  fprintf(fout,"\n\t(void)soap; (void)ptr; (void)type; /* appease -Wall -Werror */");
922	  fprintf(fout,"\n\tswitch (type)\n\t{");
923	  fflush(fout);
924          mark_defs(table);
925          fprintf(fout,"\n\t}\n}");
926        }
927	else
928	{ fprintf(fout,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap *soap, const void *ptr, int type)\n{");
929	  fprintf(fout,"\n\t(void)soap; (void)ptr; (void)type; /* appease -Wall -Werror */");
930          fprintf(fout,"\n}");
931	}
932	if (!cflag && !namespaceid)
933	  fprintf(fout,"\n\n#ifdef __cplusplus\n}\n#endif");
934	fprintf(fout,"\n#endif");
935
936	}
937
938	classflag = 0;
939	for (p = classtable->list; p; p = p->next)
940	  if (p->info.typ->type == Tclass && p->info.typ->transient <= 0)
941	  { classflag = 1;
942	    break;
943	  }
944
945	if (classflag || Tptr[Ttemplate])
946	{
947	  if (cflag)
948	    semwarn("Option -c conflicts with the use of classes");
949	}
950
951	if (!cflag)
952	{
953	fprintf(fhead,"\n\nSOAP_FMAC3 void * SOAP_FMAC4 soap_instantiate(struct soap*, int, const char*, const char*, size_t*);");
954	if (!lflag)
955	{
956	fprintf(fout,"\n\nSOAP_FMAC3 void * SOAP_FMAC4 soap_instantiate(struct soap *soap, int t, const char *type, const char *arrayType, size_t *n)\n{\n\tswitch (t)\n\t{");
957	if (classtable)
958	  for (p = classtable->list; p; p = p->next)
959	    if ((p->info.typ->type == Tclass || p->info.typ->type == Tstruct) && !is_transient(p->info.typ))
960	    { if (is_header_or_fault(p->info.typ) || is_body(p->info.typ))
961                fprintf(fout,"\n#ifndef WITH_NOGLOBAL");
962	      fprintf(fout,"\n\tcase %s:\n\t\treturn (void*)soap_instantiate_%s(soap, -1, type, arrayType, n);", soap_type(p->info.typ), c_ident(p->info.typ));
963	      if (is_header_or_fault(p->info.typ) || is_body(p->info.typ))
964                fprintf(fout,"\n#endif");
965	    }
966	if (typetable)
967	  for (p = typetable->list; p; p = p->next)
968	    if ((p->info.typ->type == Tclass || p->info.typ->type == Tstruct) && !is_transient(p->info.typ))
969	    { if (is_header_or_fault(p->info.typ) || is_body(p->info.typ))
970                fprintf(fout,"\n#ifndef WITH_NOGLOBAL");
971	      fprintf(fout,"\n\tcase %s:\n\t\treturn (void*)soap_instantiate_%s(soap, -1, type, arrayType, n);", soap_type(p->info.typ), c_ident(p->info.typ));
972	      if (is_header_or_fault(p->info.typ) || is_body(p->info.typ))
973                fprintf(fout,"\n#endif");
974	    }
975	for (typ = Tptr[Ttemplate]; typ; typ = typ->next)
976	  if (typ->ref && !is_transient(typ))
977	    fprintf(fout,"\n\tcase %s:\n\t\treturn (void*)soap_instantiate_%s(soap, -1, type, arrayType, n);", soap_type(typ), c_ident(typ));
978
979	fprintf(fout,"\n\t}\n\treturn NULL;\n}");
980	}
981
982	fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_fdelete(struct soap_clist*);");
983	if (!lflag)
984	{
985	fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_fdelete(struct soap_clist *p)");
986	fprintf(fout,"\n{\tswitch (p->type)\n\t{");
987	if (classtable)
988	{ for (p = classtable->list; p; p = p->next)
989	    if ((p->info.typ->type == Tclass || p->info.typ->type == Tstruct) && !is_transient(p->info.typ))
990	    { fprintf(fout,"\n\tcase %s:", soap_type(p->info.typ));
991	      fprintf(fout,"\n\t\tif (p->size < 0)\n\t\t\tdelete (%s*)p->ptr;\n\t\telse\n\t\t\tdelete[] (%s*)p->ptr;\n\t\tbreak;", c_type(p->info.typ), c_type(p->info.typ));
992	    }
993	}
994	if (typetable)
995	{ for (p = typetable->list; p; p = p->next)
996	    if (p->info.typ->type == Tclass || p->info.typ->type == Tstruct) /* && is_external(p->info.typ)) */
997	    { fprintf(fout,"\n\tcase %s:", soap_type(p->info.typ));
998	      fprintf(fout,"\n\t\tif (p->size < 0)\n\t\t\tdelete (%s*)p->ptr;\n\t\telse\n\t\t\tdelete[] (%s*)p->ptr;\n\t\tbreak;", c_type(p->info.typ), c_type(p->info.typ));
999	    }
1000	}
1001	for (typ = Tptr[Ttemplate]; typ; typ = typ->next)
1002	{ if (typ->ref && !is_transient(typ))
1003	  { fprintf(fout,"\n\tcase %s:", soap_type(typ));
1004	    fprintf(fout,"\n\t\tif (p->size < 0)\n\t\t\tdelete (%s*)p->ptr;\n\t\telse\n\t\t\tdelete[] (%s*)p->ptr;\n\t\tbreak;", c_type(typ), c_type(typ));
1005	  }
1006	}
1007	fprintf(fout,"\n\tdefault:\treturn SOAP_ERR;");
1008	fprintf(fout,"\n\t}\n\treturn SOAP_OK;");
1009	fprintf(fout,"\n}");
1010	}
1011
1012	fprintf(fhead,"\nSOAP_FMAC3 void* SOAP_FMAC4 soap_class_id_enter(struct soap*, const char*, void*, int, size_t, const char*, const char*);");
1013	if (!lflag)
1014	{
1015	fprintf(fout,"\n\nSOAP_FMAC3 void* SOAP_FMAC4 soap_class_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, const char *type, const char *arrayType)");
1016	fprintf(fout, "\n{\treturn soap_id_enter(soap, id, p, t, n, 0, type, arrayType, soap_instantiate);\n}");
1017	}
1018
1019	if (Tptr[Ttemplate])
1020	{
1021	fprintf(fhead, "\n\nSOAP_FMAC3 void* SOAP_FMAC4 soap_container_id_forward(struct soap*, const char*, void*, size_t, int, int, size_t, unsigned int);");
1022	if (!lflag)
1023	{
1024	fprintf(fout, "\n\nSOAP_FMAC3 void* SOAP_FMAC4 soap_container_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k)");
1025	fprintf(fout, "\n{\treturn soap_id_forward(soap, href, p, len, st, tt, n, k, soap_container_insert);\n}");
1026	}
1027
1028	fprintf(fhead, "\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_container_insert(struct soap*, int, int, void*, size_t, const void*, size_t);");
1029	if (!lflag)
1030	{
1031	fprintf(fout, "\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_container_insert(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)");
1032	fprintf(fout, "\n#ifdef WIN32\n#pragma warning(push)\n#pragma warning(disable:4065)\n#endif");
1033	fprintf(fout, "\n{\tswitch (tt)\n\t{");
1034	for (typ = Tptr[Ttemplate]; typ; typ = typ->next)
1035	{ if (typ->ref && !is_transient(typ))
1036	  { fprintf(fout, "\n\tcase %s:", soap_type(typ));
1037	    fprintf(fout, "\n\t\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Container insert type=%%d in %%d location=%%p object=%%p len=%%lu\\n\", st, tt, p, q, (unsigned long)len));");
1038            if (!strcmp(typ->id->name, "std::vector") || !strcmp(typ->id->name, "std::deque"))
1039	      fprintf(fout, "\n\t\t(*(%s)p)[len] = *(%s)q;", c_type_id(typ, "*"), c_type_id(typ->ref, "*"));
1040	    else
1041	      fprintf(fout, "\n\t\t((%s)p)->insert(((%s)p)->end(), *(%s)q);", c_type_id(typ, "*"), c_type_id(typ, "*"), c_type_id(typ->ref, "*"));
1042	    fprintf(fout, "\n\t\tbreak;");
1043	  }
1044	}
1045	fprintf(fout, "\n\tdefault:\n\t\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Could not insert type=%%d in %%d\\n\", st, tt));");
1046	fprintf(fout, "\n\t}");
1047	fprintf(fout, "\n#ifdef WIN32\n#pragma warning(pop)\n#endif");
1048	fprintf(fout, "\n}");
1049	}
1050	}
1051	}
1052
1053	DBGLOG(fprintf(stderr,"\n Calling def_table( )."));
1054        def_table(table);
1055	DBGLOG(fprintf(stderr,"\n Completed def_table( )."));
1056	if (mflag)
1057 	{ DBGLOG(fprintf(stderr,"\n Calling matlab_def_table( )."));
1058	  matlab_def_table(table);
1059 	  DBGLOG(fprintf(stderr,"\n Completed matlab_def_table( )."));
1060 	  fclose(fmatlab);
1061 	  fclose(fmheader);
1062	}
1063	if (namespaceid)
1064	  fprintf(fout,"\n\n} // namespace %s\n", namespaceid);
1065	if (cflag)
1066	  fprintf(fout,"\n\n#ifdef __cplusplus\n}\n#endif");
1067	fprintf(fout, "\n\n/* End of %s */\n", soapC);
1068        fclose(fout);
1069	if (namespaceid)
1070	  fprintf(fhead,"\n\n} // namespace %s\n", namespaceid);
1071	if (cflag)
1072	  fprintf(fhead,"\n\n#ifdef __cplusplus\n}\n#endif");
1073	fprintf(fhead, "\n\n#endif");
1074	fprintf(fhead, "\n\n/* End of %s */\n", soapH);
1075	fclose(fhead);
1076	if (namespaceid)
1077	  fprintf(fheader,"\n\n} // namespace %s\n", namespaceid);
1078	if (cflag)
1079	  fprintf(fheader,"\n\n#ifdef __cplusplus\n}\n#endif");
1080	fprintf(fheader, "\n\n#endif");
1081	fprintf(fheader, "\n\n/* End of %s */\n", soapStub);
1082	fclose(fheader);
1083
1084	if (!Sflag && !iflag)
1085	{ if (namespaceid)
1086	    fprintf(fclient,"\n\n} // namespace %s\n", namespaceid);
1087	  if (cflag)
1088	    fprintf(fclient,"\n\n#ifdef __cplusplus\n}\n#endif");
1089	  fprintf(fclient, "\n\n/* End of %s */\n", soapClient);
1090          fclose(fclient);
1091        }
1092
1093	if (!Cflag && !iflag)
1094	{ if (namespaceid)
1095	    fprintf(fserver,"\n\n} // namespace %s\n", namespaceid);
1096	  if (cflag)
1097	    fprintf(fserver,"\n\n#ifdef __cplusplus\n}\n#endif");
1098	  fprintf(fserver, "\n\n/* End of %s */\n", soapServer);
1099 	  fclose(fserver);
1100        }
1101}
1102
1103void
1104gen_class(FILE *fd, Tnode *typ)
1105{ Entry *Eptr;
1106  char *x;
1107  x = xsi_type(typ);
1108  if (!x || !*x)
1109    x = wsdl_type(typ, "");
1110  typ->generated = True;
1111  if (typ->ref)
1112  { fprintf(fheader, "\n\n#ifndef %s", soap_type(typ));
1113    fprintf(fheader, "\n#define %s (%d)\n",soap_type(typ),typ->num);
1114  }
1115  else
1116    fprintf(fd, "\n\n");
1117  if (is_volatile(typ))
1118    fprintf(fd, "#if 0 /* volatile type: do not redeclare here */\n");
1119  else if (is_transient(typ) && typ->ref)
1120    fprintf(fd, "/* Transient type: */\n");
1121  else if (is_invisible(typ->id->name) && typ->ref)
1122    fprintf(fd, "/* Operation wrapper: */\n");
1123  else if (is_hexBinary(typ))
1124    fprintf(fd, "/* hexBinary schema type: */\n");
1125  else if (is_binary(typ))
1126    fprintf(fd, "/* Base64 schema type: */\n");
1127  else if (is_discriminant(typ))
1128    fprintf(fd, "/* Choice: */\n");
1129  else if (is_dynamic_array(typ))
1130  { Eptr = ((Table*)typ->ref)->list;
1131    if (has_ns(typ) || is_untyped(typ))
1132      fprintf(fd, "/* Sequence of %s schema type: */\n", x);
1133    else
1134    { if (!eflag)
1135      { sprintf(errbuf, "array '%s' is not compliant with WS-I Basic Profile 1.0a, reason: SOAP encoded array", c_type(typ));
1136        compliancewarn(errbuf);
1137      }
1138      fprintf(fd, "/* SOAP encoded array of %s schema type: */\n", x);
1139    }
1140  }
1141  else if (is_primclass(typ))
1142    fprintf(fd, "/* Primitive %s schema type: */\n", x);
1143  else if (!strcmp(typ->id->name, "SOAP_ENV__Header"))
1144    fprintf(fd, "/* SOAP Header: */\n");
1145  else if (!strcmp(typ->id->name, "SOAP_ENV__Fault"))
1146    fprintf(fd, "/* SOAP Fault: */\n");
1147  else if (!strcmp(typ->id->name, "SOAP_ENV__Code"))
1148    fprintf(fd, "/* SOAP Fault Code: */\n");
1149  else if (x && *x && typ->ref)
1150    fprintf(fd, "/* %s */\n", x);
1151  fflush(fd);
1152  if (typ->type == Tstruct)
1153  {   DBGLOG(fprintf(stderr,"\nstruct %s\n", typ->id->name));
1154      if (typ->ref)
1155      { int permission = -1;
1156        fprintf(fd, "struct %s\n{", ident(typ->id->name));
1157        for (Eptr = ((Table*)typ->ref)->list; Eptr; Eptr = Eptr->next)
1158        { if (!cflag && permission != (Eptr->info.sto & (Sprivate | Sprotected)))
1159          { if (Eptr->info.sto & Sprivate)
1160              fprintf(fd, "\nprivate:");
1161            else if (Eptr->info.sto & Sprotected)
1162              fprintf(fd, "\nprotected:");
1163            else
1164              fprintf(fd, "\npublic:");
1165	    permission = (Eptr->info.sto & (Sprivate | Sprotected));
1166	  }
1167	  if (cflag && Eptr->info.typ->type == Tfun)
1168	    continue;
1169	  if (cflag && (Eptr->info.sto & Stypedef))
1170	    continue;
1171	  fprintf(fd, "\n\t%s", c_storage(Eptr->info.sto));
1172	  /*if (Eptr->info.typ->type == Tclass && !is_external(Eptr->info.typ) && Eptr->info.typ->generated == False || (Eptr->info.typ->type == Tpointer || Eptr->info.typ->type == Treference) && Eptr->info.typ->ref && ((Tnode*)Eptr->info.typ->ref)->type == Tclass && !is_external(Eptr->info.typ->ref) && ((Tnode*)Eptr->info.typ->ref)->generated == False)
1173	    fprintf(fd, "class ");
1174	  */
1175	  if (Eptr->sym == typ->id && Eptr->info.typ->type == Tfun) /* a hack to emit constructor in a struct, where constructor has no return value */
1176            ((FNinfo*)Eptr->info.typ->ref)->ret = mknone();
1177          fprintf(fd, "%s", c_type_id(Eptr->info.typ,Eptr->sym->name));
1178	  if (Eptr->info.sto & Sconstobj)
1179	    fprintf(fd, " const;");
1180	  else
1181	    fprintf(fd, ";");
1182	  if (Eptr->info.sto & Sreturn)
1183	    fprintf(fd, "\t/* SOAP 1.2 RPC return element (when namespace qualified) */");
1184	  if (is_external(Eptr->info.typ))
1185	    fprintf(fd, "\t/* external */");
1186	  if (is_transient(Eptr->info.typ))
1187	    fprintf(fd, "\t/* transient */");
1188	  if (is_imported(Eptr->info.typ))
1189	    fprintf(fd, "\t/* type imported from %s */", Eptr->info.typ->imported);
1190	  if (Eptr->info.sto & Sattribute)
1191	  { if (Eptr->info.minOccurs >= 1)
1192	      fprintf(fd, "\t/* required attribute of type %s */", wsdl_type(Eptr->info.typ, ""));
1193            else
1194	      fprintf(fd, "\t/* optional attribute of type %s */", wsdl_type(Eptr->info.typ, ""));
1195	  }
1196	  if (Eptr->info.sto & (Sconst | Sprivate | Sprotected))
1197	    fprintf(fd, "\t/* not serialized */");
1198	  else if (Eptr->info.sto & SmustUnderstand)
1199	    fprintf(fd, "\t/* mustUnderstand */");
1200	  else if (!is_dynamic_array(typ) && is_repetition(Eptr))
1201          { if (Eptr->info.maxOccurs > 1)
1202	      fprintf(fd, "\t/* sequence of %ld to %ld elements <%s> */", Eptr->info.minOccurs, Eptr->info.maxOccurs, ns_convert(Eptr->next->sym->name));
1203	    else
1204	      fprintf(fd, "\t/* sequence of elements <%s> */", ns_convert(Eptr->next->sym->name));
1205	  }
1206	  else if (is_anytype(Eptr))
1207	    fprintf(fd, "\t/* any type of element <%s> (defined below) */", ns_convert(Eptr->next->sym->name));
1208	  else if (is_choice(Eptr))
1209	    fprintf(fd, "\t/* union discriminant (of union defined below) */");
1210	  else if (Eptr->info.typ->type != Tfun && !(Eptr->info.sto & (Sconst | Sprivate | Sprotected)) && !(Eptr->info.sto & Sattribute) && !is_transient(Eptr->info.typ) && !is_external(Eptr->info.typ) && strncmp(Eptr->sym->name, "__", 2))
1211	  { if (Eptr->info.maxOccurs > 1)
1212	      fprintf(fd, "\t/* sequence of %ld to %ld elements of type %s */", Eptr->info.minOccurs, Eptr->info.maxOccurs, wsdl_type(Eptr->info.typ, ""));
1213	    else if (Eptr->info.minOccurs >= 1)
1214	      fprintf(fd, "\t/* required element of type %s */", wsdl_type(Eptr->info.typ, ""));
1215            else
1216	      fprintf(fd, "\t/* optional element of type %s */", wsdl_type(Eptr->info.typ, ""));
1217	  }
1218	  if (!is_dynamic_array(typ) && !is_primclass(typ))
1219	  { if (!strncmp(Eptr->sym->name, "__size", 6))
1220	    { if (!Eptr->next || Eptr->next->info.typ->type != Tpointer)
1221              { sprintf(errbuf, "Field '%s' is not followed by a pointer field in struct '%s'", Eptr->sym->name, typ->id->name);
1222                semwarn(errbuf);
1223	      }
1224	    }
1225	    else if (!strncmp(Eptr->sym->name, "__type", 6))
1226	    { if (!Eptr->next || ((Eptr->next->info.typ->type != Tpointer || ((Tnode*)Eptr->next->info.typ->ref)->type != Tvoid)))
1227              { sprintf(errbuf, "Field '%s' is not followed by a void pointer or union field in struct '%s'", Eptr->sym->name, typ->id->name);
1228                semwarn(errbuf);
1229	      }
1230	    }
1231	  }
1232	}
1233        if (!((Table*)typ->ref)->list)
1234	{ if (cflag)
1235            fprintf(fd, "\n#ifdef WITH_NOEMPTYSTRUCT\n\tchar dummy;\t/* dummy member to enable compilation */\n#endif");
1236	  else
1237            fprintf(fd, "\n#ifdef WITH_NOEMPTYSTRUCT\nprivate:\n\tchar dummy;\t/* dummy member to enable compilation */\n#endif");
1238	}
1239        fprintf(fd, "\n};");
1240      }
1241      else if (!is_transient(typ) && !is_external(typ) && !is_volatile(typ))
1242      { sprintf(errbuf, "struct '%s' is empty", typ->id->name);
1243        semwarn(errbuf);
1244      }
1245  }
1246  else if (typ->type == Tclass)
1247  { DBGLOG(fprintf(stderr,"\nclass %s\n", typ->id->name));
1248    if (typ->ref)
1249    { int permission = -1;
1250      fprintf(fd,"class SOAP_CMAC %s", ident(typ->id->name));
1251      if (typ->base)
1252        fprintf(fd," : public %s", ident(typ->base->name));
1253      fprintf(fd,"\n{");
1254      for (Eptr = ((Table*)typ->ref)->list; Eptr; Eptr = Eptr->next)
1255      { if (permission != (Eptr->info.sto & (Sprivate | Sprotected)))
1256        { if (Eptr->info.sto & Sprivate)
1257            fprintf(fd, "\nprivate:");
1258          else if (Eptr->info.sto & Sprotected)
1259            fprintf(fd, "\nprotected:");
1260          else
1261            fprintf(fd, "\npublic:");
1262	  permission = (Eptr->info.sto & (Sprivate | Sprotected));
1263	}
1264        fprintf(fd,"\n\t%s", c_storage(Eptr->info.sto));
1265	/* if (Eptr->info.typ->type == Tclass && !is_external(Eptr->info.typ) && Eptr->info.typ->generated == False || (Eptr->info.typ->type == Tpointer || Eptr->info.typ->type == Treference) && Eptr->info.typ->ref && ((Tnode*)Eptr->info.typ->ref)->type == Tclass && !is_external(Eptr->info.typ->ref) && ((Tnode*)Eptr->info.typ->ref)->generated == False)
1266	  fprintf(fd, "class ");
1267	*/
1268	fprintf(fd,"%s", c_type_id(Eptr->info.typ,Eptr->sym->name));
1269	if (Eptr->info.sto & Sconstobj)
1270	  fprintf(fd, " const");
1271	if (Eptr->info.sto & Sabstract)
1272	  fprintf(fd, " = 0;");
1273	else
1274	  fprintf(fd, ";");
1275	if (Eptr->info.sto & Sreturn)
1276	   fprintf(fd, "\t/* SOAP 1.2 RPC return element (when namespace qualified) */");
1277	 if (is_external(Eptr->info.typ))
1278	   fprintf(fd, "\t/* external */");
1279	 if (is_transient(Eptr->info.typ))
1280	   fprintf(fd, "\t/* transient */");
1281	 if (is_imported(Eptr->info.typ))
1282	   fprintf(fd, "\t/* type imported from %s */", Eptr->info.typ->imported);
1283	 if (Eptr->info.sto & Sattribute)
1284	 { if (Eptr->info.minOccurs >= 1)
1285	     fprintf(fd, "\t/* required attribute */");
1286           else
1287	     fprintf(fd, "\t/* optional attribute */");
1288	 }
1289	 if (Eptr->info.sto & (Sconst | Sprivate | Sprotected))
1290	   fprintf(fd, "\t/* not serialized */");
1291	 else if (Eptr->info.sto & SmustUnderstand)
1292	   fprintf(fd, "\t/* mustUnderstand */");
1293	 else if (!is_dynamic_array(typ) && is_repetition(Eptr))
1294         { if (Eptr->info.maxOccurs > 1)
1295	     fprintf(fd, "\t/* sequence of %ld to %ld elements <%s> */", Eptr->info.minOccurs, Eptr->info.maxOccurs, ns_convert(Eptr->next->sym->name));
1296	   else
1297	     fprintf(fd, "\t/* sequence of elements <%s> */", ns_convert(Eptr->next->sym->name));
1298	 }
1299	 else if (is_anytype(Eptr))
1300	   fprintf(fd, "\t/* any type of element <%s> (defined below) */", ns_convert(Eptr->next->sym->name));
1301	 else if (is_choice(Eptr))
1302	   fprintf(fd, "\t/* union discriminant (of union defined below) */");
1303	 else if (Eptr->info.typ->type != Tfun && !(Eptr->info.sto & (Sconst | Sprivate | Sprotected)) && !(Eptr->info.sto & Sattribute) && !is_transient(Eptr->info.typ) && !is_external(Eptr->info.typ) && strncmp(Eptr->sym->name, "__", 2))
1304	 { if (Eptr->info.maxOccurs > 1)
1305	     fprintf(fd, "\t/* sequence of %ld to %ld elements */", Eptr->info.minOccurs, Eptr->info.maxOccurs);
1306	   else if (Eptr->info.minOccurs >= 1)
1307	     fprintf(fd, "\t/* required element of type %s */", wsdl_type(Eptr->info.typ, ""));
1308           else
1309	     fprintf(fd, "\t/* optional element of type %s */", wsdl_type(Eptr->info.typ, ""));
1310	 }
1311	 if (!is_dynamic_array(typ) && !is_primclass(typ))
1312	 { if (!strncmp(Eptr->sym->name, "__size", 6))
1313	   { if (!Eptr->next || Eptr->next->info.typ->type != Tpointer)
1314             { sprintf(errbuf, "Field '%s' is not followed by a pointer field in struct '%s'", Eptr->sym->name, typ->id->name);
1315               semwarn(errbuf);
1316	     }
1317	   }
1318	   else if (!strncmp(Eptr->sym->name, "__type", 6))
1319	   { if (!Eptr->next || ((Eptr->next->info.typ->type != Tpointer || ((Tnode*)Eptr->next->info.typ->ref)->type != Tvoid)))
1320             { sprintf(errbuf, "Field '%s' is not followed by a void pointer or union field in struct '%s'", Eptr->sym->name, typ->id->name);
1321               semwarn(errbuf);
1322	     }
1323	   }
1324	 }
1325      }
1326      if (!is_transient(typ) && !is_volatile(typ))
1327      { fprintf(fd,"\npublic:\n\tvirtual int soap_type() const { return %d; } /* = unique id %s */", typ->num, soap_type(typ));
1328        fprintf(fd,"\n\tvirtual void soap_default(struct soap*);");
1329        fprintf(fd,"\n\tvirtual void soap_serialize(struct soap*) const;");
1330        fprintf(fd,"\n\tvirtual int soap_put(struct soap*, const char*, const char*) const;");
1331        fprintf(fd,"\n\tvirtual int soap_out(struct soap*, const char*, int, const char*) const;");
1332        fprintf(fd,"\n\tvirtual void *soap_get(struct soap*, const char*, const char*);");
1333        fprintf(fd,"\n\tvirtual void *soap_in(struct soap*, const char*, const char*);");
1334	if (!has_constructor(typ))
1335	{ Table *t;
1336	  Entry *p;
1337	  int c = ':';
1338	  fprintf(fd,"\n\t         %s() ", ident(typ->id->name));
1339          t = (Table*)typ->ref;
1340	  if (t)
1341          { for (p = t->list; p; p = p->next)
1342	    { if (!(p->info.sto & Sconst))
1343	      { char *val = c_init(p);
1344	        if (p->info.hasval && *val)
1345	        { fprintf(fd, "%c %s(%s)", c, ident(p->sym->name), val + 3);
1346	          c = ',';
1347	        }
1348	        else if (p->info.typ->type == Tpointer)
1349	        { fprintf(fd, "%c %s(NULL)", c, ident(p->sym->name));
1350	          c = ',';
1351	        }
1352	        else if (is_choice(p))
1353	        { fprintf(fd, "%c %s(0)", c, ident(p->sym->name));
1354	          c = ',';
1355	        }
1356	        else if (p->info.typ->type == Tenum)
1357	        { fprintf(fd, "%c %s((%s)0)", c, ident(p->sym->name), c_type(p->info.typ));
1358	          c = ',';
1359	        }
1360	        else if (p->info.typ->type >= Tchar && p->info.typ->type < Tenum)
1361	        { fprintf(fd, "%c %s(0)", c, ident(p->sym->name));
1362	          c = ',';
1363	        }
1364	      }
1365	    }
1366	  }
1367	  fprintf(fd," { }");
1368	}
1369	if (!has_destructor(typ))
1370	  fprintf(fd,"\n\tvirtual ~%s() { }", ident(typ->id->name));
1371	/* the use of 'friend' causes problems linking static functions. Adding these friends could enable serializing protected/private members (which is not implemented)
1372        fprintf(fd,"\n\tfriend %s *soap_instantiate_%s(struct soap*, int, const char*, const char*, size_t*);", typ->id->name, typ->id->name);
1373        fprintf(fd,"\n\tfriend %s *soap_in_%s(struct soap*, const char*, %s*, const char*);", typ->id->name, typ->id->name, typ->id->name);
1374        fprintf(fd,"\n\tfriend int soap_out_%s(struct soap*, const char*, int, const %s*, const char*);", typ->id->name, typ->id->name);
1375        */
1376      }
1377      else if (!((Table*)typ->ref)->list)
1378        fprintf(fd, "\n#ifdef WITH_NOEMPTYSTRUCT\nprivate:\n\tchar dummy;\t/* dummy member to enable compilation */\n#endif");
1379      fprintf(fd,"\n};");
1380    }
1381    else if (!is_transient(typ) && !is_external(typ) && !is_volatile(typ))
1382    { sprintf(errbuf, "class '%s' is empty", typ->id->name);
1383      semwarn(errbuf);
1384    }
1385  }
1386  else if (typ->type == Tunion)
1387  { int i = 1;
1388      if (typ->ref)
1389      { fprintf(fd, "union %s\n{", ident(typ->id->name));
1390        for (Eptr = ((Table*)typ->ref)->list; Eptr; Eptr = Eptr->next)
1391	{ fprintf(fd, "\n#define SOAP_UNION_%s_%s\t(%d)", c_ident(typ), ident(Eptr->sym->name), i);
1392	  i++;
1393	  fprintf(fd, "\n\t%s", c_storage(Eptr->info.sto));
1394          fprintf(fd, "%s;", c_type_id(Eptr->info.typ,Eptr->sym->name));
1395	  if (Eptr->info.sto & (Sconst | Sprivate | Sprotected))
1396	    fprintf(fd, "\t/* const field cannot be deserialized */");
1397	  if (is_external(Eptr->info.typ))
1398	    fprintf(fd, "\t/* external */");
1399	  if (is_transient(Eptr->info.typ))
1400	    fprintf(fd, "\t/* transient */");
1401	  if (Eptr->info.sto & Sattribute)
1402	  { fprintf(fd, "\t/* attribute not allowed in union */");
1403            sprintf(errbuf, "union '%s' contains attribute declarations", typ->id->name);
1404            semwarn(errbuf);
1405	  }
1406	  if (Eptr->info.sto & SmustUnderstand)
1407	    fprintf(fd, "\t/* mustUnderstand */");
1408	}
1409        fprintf(fd, "\n};");
1410      }
1411      else if (!is_transient(typ) && !is_external(typ) && !is_volatile(typ))
1412      { sprintf(errbuf, "union '%s' is empty", typ->id->name);
1413        semwarn(errbuf);
1414      }
1415  }
1416  if (is_volatile(typ))
1417    fprintf(fd, "\n#endif");
1418  if (typ->ref)
1419    fprintf(fd, "\n#endif");
1420  fflush(fd);
1421}
1422
1423void
1424generate_header(Table *t)
1425{ Entry *p, *q;
1426  banner(fheader, "Enumerations");
1427  fflush(fheader);
1428  if (enumtable)
1429    for (p = enumtable->list; p; p = p->next)
1430    { char *x;
1431      if (is_imported(p->info.typ) || (is_transient(p->info.typ) && !p->info.typ->ref))
1432        continue;
1433      x = xsi_type(p->info.typ);
1434      if (!x || !*x)
1435        x = wsdl_type(p->info.typ, "");
1436      fprintf(fheader, "\n\n#ifndef %s", soap_type(p->info.typ));
1437      fprintf(fheader, "\n#define %s (%d)",soap_type(p->info.typ),p->info.typ->num);
1438      if (is_volatile(p->info.typ))
1439        fprintf(fheader, "\n#if 0 /* volatile type: do not redeclare here */");
1440      if (is_mask(p->info.typ))
1441        fprintf(fheader, "\n/* Bitmask %s */", x);
1442      else
1443        fprintf(fheader, "\n/* %s */", x);
1444      fprintf(fheader, "\nenum %s {", ident(p->info.typ->id->name));
1445      if ((Table*)p->info.typ->ref)
1446      { q = ((Table*)p->info.typ->ref)->list;
1447        if (q)
1448        { fprintf(fheader, "%s = "SOAP_LONG_FORMAT, ident(q->sym->name), q->info.val.i);
1449          for (q = q->next; q; q = q->next)
1450            fprintf(fheader, ", %s = "SOAP_LONG_FORMAT, ident(q->sym->name), q->info.val.i);
1451        }
1452      }
1453      fprintf(fheader, "};\n#endif");
1454      if (is_volatile(p->info.typ))
1455        fprintf(fheader, "\n#endif");
1456    }
1457  banner(fheader, "Classes and Structs");
1458  fflush(fheader);
1459  /* Obsolete: moved unions in classtable
1460  if (uniontable)
1461    for (p = uniontable->list; p; p = p->next)
1462      if (!is_imported(p->info.typ))
1463        gen_union(fheader, p->info.typ);
1464  */
1465  if (classtable)
1466    for (p = classtable->list; p; p = p->next)
1467      if (!is_imported(p->info.typ))
1468        gen_class(fheader, p->info.typ);
1469  banner(fheader, "Types with Custom Serializers");
1470  fflush(fheader);
1471  if (typetable)
1472    for (p = typetable->list; p; p = p->next)
1473    { if (is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_imported(p->info.typ))
1474      { fprintf(fheader, "\n#ifndef %s", soap_type(p->info.typ));
1475	fprintf(fheader, "\n#define %s (%d)",soap_type(p->info.typ),p->info.typ->num);
1476        fprintf(fheader, "\n%s%s;", c_storage(p->info.sto), c_type_id(p->info.typ, p->sym->name));
1477        fprintf(fheader, "\n#endif");
1478      }
1479    }
1480  banner(fheader, "Typedefs");
1481  fflush(fheader);
1482  if (typetable)
1483    for (p = typetable->list; p; p = p->next)
1484    { if (!is_primitive_or_string(p->info.typ) && !is_external(p->info.typ) && !is_XML(p->info.typ) && !is_transient(p->info.typ) && !has_ns_t(p->info.typ) && !is_imported(p->info.typ) && !is_template(p->info.typ))
1485      { sprintf(errbuf, "typedef '%s' is not namespace qualified: schema definition for '%s' in WSDL file output may be invalid", p->sym->name, p->sym->name);
1486        semwarn(errbuf);
1487      }
1488      if (!is_external(p->info.typ) && !is_imported(p->info.typ))
1489      { fprintf(fheader, "\n#ifndef %s", soap_type(p->info.typ));
1490	fprintf(fheader, "\n#define %s (%d)",soap_type(p->info.typ),p->info.typ->num);
1491        fprintf(fheader,"\n%s%s;", c_storage(p->info.sto), c_type_id(p->info.typ, p->sym->name));
1492        fprintf(fheader, "\n#endif\n");
1493      }
1494    }
1495  banner(fheader, "Typedef Synonyms");
1496  if (enumtable)
1497    for (p = enumtable->list; p; p = p->next)
1498      if (p->sym->token == TYPE)
1499        fprintf(fheader, "\ntypedef %s %s;", c_type(p->info.typ), ident(p->sym->name));
1500  if (classtable)
1501    for (p = classtable->list; p; p = p->next)
1502      if ((p->info.typ->type == Tstruct || p->info.typ->type == Tunion) && p->sym->token == TYPE)
1503        fprintf(fheader, "\ntypedef %s %s;", c_type(p->info.typ), ident(p->sym->name));
1504  banner(fheader, "Externals");
1505  fflush(fheader);
1506  if (t)
1507    for (p = t->list; p; p = p->next)
1508      if (p->info.typ->type != Tfun || p->info.sto & Sextern)
1509      { fprintf(fheader,"\n\nextern %s", c_storage(p->info.sto));
1510        fprintf(fheader,"%s;", c_type_id(p->info.typ, p->sym->name));
1511      }
1512  fflush(fheader);
1513}
1514
1515void
1516get_namespace_prefixes()
1517{ Symbol *p, *q;
1518  int i, n;
1519  char *s, buf[256];
1520  if (nslist)
1521    return;
1522  for (p = symlist; p; p = p->next)
1523  { if (*p->name != '~')
1524    { s = p->name;
1525      while (*s == '_')
1526	s++;
1527      n = (int)(strlen(s) - 2);
1528      for (i = 1; i < n; i++)
1529      { if ((s[i] == '_' && s[i+1] == '_' && s[i+2] && s[i+2] != '_') || s[i] == ':')
1530        { if (s[i+1] == ':')
1531	  { i++;
1532	    continue;
1533	  }
1534	  strncpy(buf, s, i);
1535          buf[i] = '\0';
1536	  if (!strcmp(buf, "SOAP_ENV") || !strcmp(buf, "SOAP_ENC") || !strcmp(buf, "xsd") || !strcmp(buf, "xsi") || !strcmp(buf, "xml") || !strcmp(buf, "std") || !strncmp(buf, "soap_", 5))
1537	    goto nsnext;
1538          for (q = nslist; q; q = q->next)
1539            if (!strcmp(q->name, buf))
1540              goto nsnext;
1541          q = (Symbol*)emalloc(sizeof(Symbol));
1542          q->name = (char*)emalloc(i+1);
1543	  strcpy(q->name, buf);
1544	  q->name[i] = '\0';
1545	  q->next = nslist;
1546	  nslist = q;
1547	  break;
1548        }
1549      }
1550    }
1551nsnext:
1552    ;
1553  }
1554  q = (Symbol*)emalloc(sizeof(Symbol));
1555  q->name = "xsd";
1556  q->next = nslist;
1557  nslist = q;
1558  q = (Symbol*)emalloc(sizeof(Symbol));
1559  q->name = "xsi";
1560  q->next = nslist;
1561  nslist = q;
1562  q = (Symbol*)emalloc(sizeof(Symbol));
1563  q->name = "SOAP-ENC";
1564  q->next = nslist;
1565  nslist = q;
1566  q = (Symbol*)emalloc(sizeof(Symbol));
1567  q->name = "SOAP-ENV";
1568  q->next = nslist;
1569  nslist = q;
1570}
1571
1572void
1573generate_schema(Table *t)
1574{ Entry *p;
1575  Symbol *ns;
1576  char *name = NULL;
1577  char *URL = NULL;
1578  char *executable = NULL;
1579  char *URI = NULL;
1580  char *style = NULL;
1581  char *encoding = NULL;
1582  char *import = NULL;
1583  Service *sp = NULL;
1584  char buf[1024];
1585  FILE *fd;
1586  int flag = 0;
1587  get_namespace_prefixes();
1588  for (ns = nslist; ns; ns = ns->next)
1589  { if (!strcmp(ns->name, "SOAP-ENV") || !strcmp(ns->name, "SOAP-ENC") || !strcmp(ns->name, "xsi") || !strcmp(ns->name, "xsd"))
1590      continue;
1591    name = NULL;
1592    URL = NULL;
1593    executable = NULL;
1594    URI = NULL;
1595    style = NULL;
1596    encoding = NULL;
1597    import = NULL;
1598    for (sp = services; sp; sp = sp->next)
1599    { if (!tagcmp(sp->ns, ns->name))
1600	{	name = ns_cname(sp->name, NULL);
1601		URL = sp->URL;
1602		executable = sp->executable;
1603		URI = sp->URI;
1604		style = sp->style;
1605		encoding = sp->encoding;
1606		import = sp->import;
1607		break;
1608  	}
1609    }
1610    if (!URI)
1611    { URI = emalloc(strlen(tmpURI) + strlen(ns->name) + 6);
1612      sprintf(URI, "%s/%s.xsd", tmpURI, ns_convert(ns->name));
1613    }
1614    if (is_document(style) && encoding && !*encoding)
1615    {	semwarn("Cannot use document style with SOAP encoding");
1616    	encoding = NULL;
1617    }
1618    if (!name)
1619  	name = "Service";
1620    if (!URL)
1621  	URL = "http://localhost:80";
1622    if (!import)
1623      flag = 1;
1624    if (t)
1625    { for (p = t->list; p; p = p->next)
1626      { if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns->name, p->sym->name))
1627	{ if (name)
1628	    fprintf(fmsg, "Using %s service name: %s\n", ns->name, name);
1629	  if (style)
1630	    fprintf(fmsg, "Using %s service style: %s\n", ns->name, style);
1631	  else if (!eflag)
1632	    fprintf(fmsg, "Using %s service style: document\n", ns->name);
1633	  if (encoding && *encoding)
1634	    fprintf(fmsg, "Using %s service encoding: %s\n", ns->name, encoding);
1635	  else if (encoding && !*encoding)
1636	    fprintf(fmsg, "Using %s service encoding: encoded\n", ns->name);
1637	  else if (!eflag)
1638	    fprintf(fmsg, "Using %s service encoding: literal\n", ns->name);
1639	  if (URL)
1640	    fprintf(fmsg, "Using %s service location: %s\n", ns->name, URL);
1641	  if (executable)
1642	    fprintf(fmsg, "Using %s service executable: %s\n", ns->name, executable);
1643	  if (import)
1644	    fprintf(fmsg, "Using %s schema import: %s\n", ns->name, import);
1645	  else if (URI)
1646	    fprintf(fmsg, "Using %s schema namespace: %s\n", ns->name, URI);
1647          if (sp && sp->name)
1648	    sprintf(buf, "%s%s.wsdl", dirpath, ns_cname(name, NULL));
1649	  else
1650	    sprintf(buf, "%s%s.wsdl", dirpath, ns_cname(ns->name, NULL));
1651	  if (!wflag && !import)
1652	  { fprintf(fmsg, "Saving %s Web Service description\n", buf);
1653            fd = fopen(buf, "w");
1654	    if (!fd)
1655	      execerror("Cannot write WSDL file");
1656            gen_wsdl(fd, t, ns->name, name, URL, executable, URI, style, encoding);
1657            fclose(fd);
1658	  }
1659	  if (!cflag)
1660	  { if (iflag)
1661            { char *sname;
1662	      if (sp && sp->name)
1663	        sname = sp->name;
1664              else
1665	        sname = "";
1666	      if (!Sflag)
1667              { char *name1 = ns_cname(sname, "Proxy");
1668	        sprintf(buf, "%s%s%s.h", dirpath, prefix, name1);
1669	        fprintf(fmsg, "Saving %s client proxy class\n", buf);
1670                fd = fopen(buf, "w");
1671	        if (!fd)
1672	          execerror("Cannot write proxy class file");
1673	        sprintf(buf, "%s%s.h", prefix, name1);
1674	        copyrightnote(fd, buf);
1675                gen_proxy_header(fd, t, ns, name1, URL, executable, URI, encoding);
1676                fclose(fd);
1677	        sprintf(buf, "%s%s%s.cpp", dirpath, prefix, name1);
1678	        fprintf(fmsg, "Saving %s client proxy class\n", buf);
1679                fd = fopen(buf, "w");
1680	        if (!fd)
1681	          execerror("Cannot write proxy class file");
1682	        sprintf(buf, "%s%s.cpp", prefix, name1);
1683	        copyrightnote(fd, buf);
1684                gen_proxy_code(fd, t, ns, name1, URL, executable, URI, encoding);
1685                fclose(fd);
1686	      }
1687              if (!Cflag)
1688              { char *name1 = ns_cname(sname, "Service");
1689	        sprintf(buf, "%s%s%s.h", dirpath, prefix, name1);
1690	        fprintf(fmsg, "Saving %s service class\n", buf);
1691                fd = fopen(buf, "w");
1692	        if (!fd)
1693	          execerror("Cannot write service class file");
1694	        sprintf(buf, "%s%s.h", prefix, name1);
1695	        copyrightnote(fd, buf);
1696                gen_object_header(fd, t, ns, name1, URL, executable, URI, encoding);
1697                fclose(fd);
1698	        sprintf(buf, "%s%s%s.cpp", dirpath, prefix, name1);
1699	        fprintf(fmsg, "Saving %s service class\n", buf);
1700                fd = fopen(buf, "w");
1701	        if (!fd)
1702	          execerror("Cannot write service class file");
1703	        sprintf(buf, "%s%s.cpp", prefix, name1);
1704	        copyrightnote(fd, buf);
1705                gen_object_code(fd, t, ns, name1, URL, executable, URI, encoding);
1706                fclose(fd);
1707	      }
1708	    }
1709	    else
1710	    { if (!Sflag && sp && sp->name)
1711	      { sprintf(buf, "%s%s%s.h", dirpath, prefix, ns_cname(name, "Proxy"));
1712	        fprintf(fmsg, "Saving %s client proxy\n", buf);
1713                fd = fopen(buf, "w");
1714	        if (!fd)
1715	          execerror("Cannot write proxy file");
1716	        sprintf(buf, "%s%s.h", prefix, ns_cname(name, "Proxy"));
1717	        copyrightnote(fd, buf);
1718                gen_proxy(fd, t, ns, name, URL, executable, URI, encoding);
1719                fclose(fd);
1720	      }
1721	      else if (!Sflag)
1722	      { sprintf(buf, "%s%s.h", dirpath, ns_cname(prefix, "Proxy"));
1723	        fprintf(fmsg, "Saving %s client proxy\n", buf);
1724                fd = fopen(buf, "w");
1725	        if (!fd)
1726	          execerror("Cannot write proxy file");
1727	        sprintf(buf, "%s.h", ns_cname(prefix, "Proxy"));
1728	        copyrightnote(fd, buf);
1729                gen_proxy(fd, t, ns, "Service", URL, executable, URI, encoding);
1730                fclose(fd);
1731	      }
1732              if (!Cflag && sp && sp->name)
1733	      { sprintf(buf, "%s%s%s.h", dirpath, prefix, ns_cname(name, "Object"));
1734	        fprintf(fmsg, "Saving %s server object\n", buf);
1735                fd = fopen(buf, "w");
1736	        if (!fd)
1737	          execerror("Cannot write server object file");
1738	        sprintf(buf, "%s%s.h", prefix, ns_cname(name, "Object"));
1739	        copyrightnote(fd, buf);
1740                gen_object(fd, t, ns, name, URL, executable, URI, encoding);
1741                fclose(fd);
1742	      }
1743	      else if (!Cflag)
1744	      { sprintf(buf, "%s%s.h", dirpath, ns_cname(prefix, "Object"));
1745	        fprintf(fmsg, "Saving %s server object\n", buf);
1746                fd = fopen(buf, "w");
1747	        if (!fd)
1748	          execerror("Cannot write server object file");
1749	        sprintf(buf, "%s.h", ns_cname(prefix, "Object"));
1750	        copyrightnote(fd, buf);
1751                gen_object(fd, t, ns, "Service", URL, executable, URI, encoding);
1752                fclose(fd);
1753	      }
1754	    }
1755	  }
1756	  if (!xflag)
1757	  { strcpy(buf, dirpath);
1758            if (sp && sp->name)
1759	      strcat(buf, ns_cname(name, NULL));
1760	    else
1761	      strcat(buf, ns_cname(ns->name, NULL));
1762	    strcat(buf, ".");
1763            gen_data(buf, t, ns->name, name, URL, executable, URI, encoding);
1764	  }
1765	  break;
1766        }
1767      }
1768      if (sp && sp->name)
1769      { has_nsmap = 1;
1770        if (nflag)
1771	  sprintf(buf, "%s%s.nsmap", dirpath, prefix);
1772        else
1773	  sprintf(buf, "%s%s.nsmap", dirpath, ns_cname(name, NULL));
1774        fprintf(fmsg, "Saving %s namespace mapping table\n", buf);
1775        fd = fopen(buf, "w");
1776	if (!fd)
1777	  execerror("Cannot write nsmap file");
1778	fprintf(fd, "\n#include \"%sH.h\"", prefix);
1779 	if (nflag)
1780	  fprintf(fd, "\nSOAP_NMAC struct Namespace %s_namespaces[] =\n", prefix);
1781 	else
1782 	  fprintf(fd, "\nSOAP_NMAC struct Namespace namespaces[] =\n");
1783	gen_nsmap(fd, ns, URI);
1784        fclose(fd);
1785      }
1786    }
1787    if (!wflag && !import)
1788    { sprintf(buf, "%s%s.xsd", dirpath, ns_cname(ns->name, NULL));
1789      fprintf(fmsg, "Saving %s XML schema\n", buf);
1790      fd = fopen(buf, "w");
1791      if (!fd)
1792        execerror("Cannot write schema file");
1793      fprintf(fd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1794      if (t)
1795        for (p = t->list; p; p = p->next)
1796          if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns->name, p->sym->name))
1797          { gen_schema(fd, t, ns->name, ns->name, 0, 1, URL, URI, style, encoding);
1798	    break;
1799          }
1800      if (!t || !p)
1801        gen_schema(fd, t, ns->name, ns->name, 0, 0, URL, URI, style, encoding);
1802      fclose(fd);
1803    }
1804  }
1805  if (!has_nsmap && flag)
1806  { for (ns = nslist; ns; ns = ns->next)
1807      if (strcmp(ns->name, "SOAP-ENV") && strcmp(ns->name, "SOAP-ENC") && strcmp(ns->name, "xsi") && strcmp(ns->name, "xsd"))
1808        break;
1809    if (nflag)
1810      sprintf(buf, "%s%s.nsmap", dirpath, prefix);
1811    else if (ns && ns->name)
1812      sprintf(buf, "%s%s.nsmap", dirpath, ns_cname(ns->name, NULL));
1813    else
1814      sprintf(buf, "%ssoap.nsmap", dirpath);
1815    fprintf(fmsg, "Saving %s namespace mapping table\n", buf);
1816    fd = fopen(buf, "w");
1817    if (!fd)
1818      execerror("Cannot write nsmap file");
1819    fprintf(fd, "\n#include \"%sH.h\"", prefix);
1820    if (nflag)
1821      fprintf(fd, "\nSOAP_NMAC struct Namespace %s_namespaces[] =\n", prefix);
1822    else
1823      fprintf(fd, "\nSOAP_NMAC struct Namespace namespaces[] =\n");
1824    gen_nsmap(fd, ns, URI);
1825    fclose(fd);
1826  }
1827}
1828
1829int
1830chkhdr(char *part)
1831{ Entry *p;
1832  p = entry(classtable, lookup("SOAP_ENV__Header"));
1833  if (p)
1834    for (p = ((Table*)p->info.typ->ref)->list; p; p = p->next)
1835      if (has_ns_eq(NULL, p->sym->name) && (!strcmp(part, p->sym->name) || is_eq_nons(part, p->sym->name)))
1836        return 1;
1837  sprintf(errbuf, "Cannot define method-header-part in WSDL: SOAP_ENV__Header \"%s\" field is not qualified", part);
1838  semwarn(errbuf);
1839  return 0;
1840}
1841
1842void
1843gen_wsdl(FILE *fd, Table *t, char *ns, char *name, char *URL, char *executable, char *URI, char *style, char *encoding)
1844{ Entry *p, *q, *r;
1845  Symbol *s;
1846  Service *sp, *sp2;
1847  Method *m;
1848  int mimein, mimeout;
1849  char *action, *comment, *method_style = NULL, *method_encoding = NULL, *method_response_encoding = NULL;
1850  char *portname;
1851  char *binding;
1852  fprintf(fd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1853  for (sp = services; sp; sp = sp->next)
1854    if (!tagcmp(sp->ns, ns))
1855      break;
1856  if (sp && sp->definitions)
1857    fprintf(fd, "<definitions name=\"%s\"\n", sp->definitions);
1858  else
1859    fprintf(fd, "<definitions name=\"%s\"\n", name);
1860  if (sp && sp->WSDL)
1861    fprintf(fd, " targetNamespace=\"%s\"\n xmlns:tns=\"%s\"", sp->WSDL, sp->WSDL);
1862  else
1863    fprintf(fd, " targetNamespace=\"%s/%s.wsdl\"\n xmlns:tns=\"%s/%s.wsdl\"", URL, name, URL, name);
1864  if (sp && sp->binding)
1865    binding = ns_cname(sp->binding, NULL);
1866  else
1867    binding = name;
1868  if (sp && sp->portname)
1869    portname = ns_cname(sp->portname, NULL);
1870  else
1871    portname = name;
1872  for (s = nslist; s; s = s->next)
1873  { for (sp2 = services; sp2; sp2 = sp2->next)
1874      if (!tagcmp(sp2->ns, s->name) && sp2->URI)
1875        break;
1876    if (sp2)
1877      fprintf(fd, "\n xmlns:%s=\"%s\"", ns_convert(s->name), sp2->URI);
1878    else if (!strcmp(s->name, "SOAP-ENV"))
1879      fprintf(fd, "\n xmlns:SOAP-ENV=\"%s\"", envURI);
1880    else if (!strcmp(s->name, "SOAP-ENC"))
1881      fprintf(fd, "\n xmlns:SOAP-ENC=\"%s\"", encURI);
1882    else if (!strcmp(s->name, "xsi"))
1883      fprintf(fd, "\n xmlns:xsi=\"%s\"", xsiURI);
1884    else if (!strcmp(s->name, "xsd"))
1885      fprintf(fd, "\n xmlns:xsd=\"%s\"", xsdURI);
1886    else
1887      fprintf(fd, "\n xmlns:%s=\"%s/%s.xsd\"", ns_convert(s->name), tmpURI, ns_convert(s->name));
1888  }
1889  if (is_soap12(encoding))
1890    fprintf(fd, "\n xmlns:SOAP=\"http://schemas.xmlsoap.org/wsdl/soap12/\"");
1891  else
1892    fprintf(fd, "\n xmlns:SOAP=\"http://schemas.xmlsoap.org/wsdl/soap/\"");
1893  fprintf(fd, "\n xmlns:MIME=\"http://schemas.xmlsoap.org/wsdl/mime/\"");
1894  fprintf(fd, "\n xmlns:DIME=\"http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/\"");
1895  fprintf(fd, "\n xmlns:WSDL=\"http://schemas.xmlsoap.org/wsdl/\"");
1896  fprintf(fd, "\n xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n\n");
1897  fprintf(fd, "<types>\n\n");
1898  for (s = nslist; s; s = s->next)
1899    gen_schema(fd, t, ns, s->name, !strcmp(s->name, ns), 1, URL, URI, style, encoding);
1900  fprintf(fd, "</types>\n\n");
1901  fflush(fd);
1902  if (t)
1903  { for (p = t->list; p; p = p->next)
1904    { if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns, p->sym->name))
1905      { mimein = 0;
1906        mimeout = 0;
1907	comment = NULL;
1908        method_style = style;
1909	method_encoding = encoding;
1910	method_response_encoding = NULL;
1911	if (sp)
1912	{   for (m = sp->list; m; m = m->next)
1913	    { if (is_eq_nons(m->name, p->sym->name))
1914	      { if (m->mess&MIMEIN)
1915		  mimein = 1;
1916	        if (m->mess&MIMEOUT)
1917		  mimeout = 1;
1918                if (m->mess == ENCODING)
1919	          method_encoding = m->part;
1920                else if (m->mess == RESPONSE_ENCODING)
1921	          method_response_encoding = m->part;
1922                else if (m->mess == STYLE)
1923	          method_style = m->part;
1924	        else if (m->mess == COMMENT)
1925	          comment = m->part;
1926	      }
1927	    }
1928	}
1929        if (!method_response_encoding)
1930          method_response_encoding = method_encoding;
1931	if (get_response(p->info.typ))
1932          fprintf(fd, "<message name=\"%sRequest\">\n", ns_remove(p->sym->name));
1933	else
1934          fprintf(fd, "<message name=\"%s\">\n", ns_remove(p->sym->name));
1935        fflush(fd);
1936	if (is_document(method_style))
1937	{ if (is_invisible(p->sym->name))
1938	  { q = entry(classtable, p->sym);
1939	    if (q)
1940	    { q = ((Table*)q->info.typ->ref)->list;
1941	      if (q)
1942	      { if (is_invisible(q->sym->name))
1943	        { r = entry(classtable, q->sym);
1944		  if (r)
1945		  { r = ((Table*)r->info.typ->ref)->list;
1946		    if (r)
1947		      fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_add(r->sym->name, ns));
1948		  }
1949		}
1950                else
1951	          fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_add(q->sym->name, ns));
1952	      }
1953	    }
1954	  }
1955	  else
1956	    fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_add(p->sym->name, ns));
1957	}
1958	else
1959  	{ q = entry(classtable, p->sym);
1960  	  if (q)
1961	    for (q = ((Table*)q->info.typ->ref)->list; q; q = q->next)
1962	    { if (!is_transient(q->info.typ) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun && !is_repetition(q) && !is_anytype(q))
1963  	      { if (is_literal(method_encoding))
1964	          fprintf(fd, " <part name=\"%s\" element=\"%s\"/>\n", ns_remove(q->sym->name), ns_add(q->sym->name, ns));
1965	        else if (is_XML(q->info.typ))
1966	          fprintf(fd, " <part name=\"parameters\" type=\"xsd:anyType\"/>\n");
1967	        else
1968	          fprintf(fd, " <part name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns));
1969	      }
1970	    }
1971	}
1972	if (mimein)
1973          fprintf(fd, " <part name=\"attachments\" type=\"xsd:base64Binary\"/>\n");
1974        fprintf(fd, "</message>\n\n");
1975        fflush(fd);
1976	q = (Entry*)p->info.typ->ref;
1977        for (r = t->list; r; r = r->next)
1978          if (r != p && r->info.typ->type == Tfun && !(r->info.sto & Sextern) && q == r->info.typ->ref)
1979	    q = NULL;
1980	if (q && is_transient(q->info.typ))
1981	  ;
1982	else if (q && !is_response(q->info.typ))
1983        { fprintf(fd, "<message name=\"%sResponse\">\n", ns_remove(p->sym->name));
1984	  if (is_document(method_style))
1985	    fprintf(fd, " <part name=\"parameters\" element=\"%sResponse\"/>\n", ns_add(p->sym->name, ns));
1986  	  else if (is_literal(method_response_encoding))
1987	    fprintf(fd, " <part name=\"%s\" element=\"%s\"/>\n", ns_remove(q->sym->name), ns_add(q->sym->name, ns));
1988	  else if (is_XML(q->info.typ->ref))
1989	    fprintf(fd, " <part name=\"parameters\" type=\"xsd:anyType\"/>\n");
1990	  else
1991	    fprintf(fd, " <part name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns));
1992	  if (mimeout)
1993            fprintf(fd, " <part name=\"attachments\" type=\"xsd:base64Binary\"/>\n");
1994          fprintf(fd, "</message>\n\n");
1995	}
1996        else if (q && q->info.typ->wsdl == False)
1997	{ q->info.typ->wsdl = True;
1998	  fprintf(fd, "<message name=\"%s\">\n", ns_remove(((Tnode*)q->info.typ->ref)->id->name));
1999	  if (is_document(method_style))
2000	  { if (has_ns_eq(NULL, ((Entry*)p->info.typ->ref)->sym->name))
2001	      fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_convert(((Entry*)p->info.typ->ref)->sym->name));
2002            else if (is_invisible(((Tnode*)q->info.typ->ref)->id->name))
2003	    { r = ((Table*)((Tnode*)q->info.typ->ref)->ref)->list;
2004	      if (r)
2005	        fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_add(r->sym->name, ns));
2006	    }
2007            else
2008	      fprintf(fd, " <part name=\"parameters\" element=\"%s\"/>\n", ns_convert(((Tnode*)q->info.typ->ref)->id->name));
2009	  }
2010	  else
2011	  { if (((Tnode*)q->info.typ->ref)->ref)
2012	    { for (q = ((Table*)((Tnode*)q->info.typ->ref)->ref)->list; q; q = q->next)
2013	      { if (!is_transient(q->info.typ) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun && !is_repetition(q) && !is_anytype(q))
2014  	        { if (is_literal(method_response_encoding))
2015	            fprintf(fd, " <part name=\"%s\" element=\"%s\"/>\n", ns_remove(q->sym->name), ns_add(q->sym->name, ns));
2016	          else if (is_XML(q->info.typ))
2017	            fprintf(fd, " <part name=\"parameters\" type=\"xsd:anyType\"/>\n");
2018	          else
2019	            fprintf(fd, " <part name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns));
2020	        }
2021	      }
2022	    }
2023	  }
2024	  if (mimeout)
2025            fprintf(fd, " <part name=\"attachments\" type=\"xsd:base64Binary\"/>\n");
2026          fprintf(fd, "</message>\n\n");
2027	}
2028        fflush(fd);
2029      }
2030    }
2031    if (custom_header)
2032    { Table *r;
2033      fprintf(fd, "<message name=\"%sHeader\">\n", name);
2034      r = entry(classtable, lookup("SOAP_ENV__Header"))->info.typ->ref;
2035      if (r)
2036      { for (q = r->list; q; q = q->next)
2037	{ if (!is_transient(q->info.typ) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun && !is_repetition(q) && !is_anytype(q))
2038	    fprintf(fd, " <part name=\"%s\" element=\"%s\"/>\n", ns_remove(q->sym->name), ns_add(q->sym->name, ns));
2039        }
2040      }
2041      fprintf(fd, "</message>\n\n");
2042    }
2043    if (custom_fault)
2044    { Table *r;
2045      fprintf(fd, "<message name=\"%sFault\">\n", name);
2046      r = entry(classtable, lookup("SOAP_ENV__Detail"))->info.typ->ref;
2047      if (r)
2048        for (q = r->list; q; q = q->next)
2049	  if (!is_transient(q->info.typ) && !is_repetition(q) && !is_anytype(q) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun && has_ns_eq(NULL, q->sym->name))
2050	    fprintf(fd, " <part name=\"%s\" element=\"%s\"/>\n", ns_remove(q->sym->name), ns_add(q->sym->name, ns));
2051      fprintf(fd, "</message>\n\n");
2052    }
2053    if (sp)
2054    { for (m = sp->list; m; m = m->next)
2055      { if (m->mess&FAULT && m->part)
2056        { Method *m2;
2057	  int flag = 0;
2058	  for (m2 = sp->list; m2 && m2 != m; m2 = m2->next)
2059	    if (m2->mess&FAULT && !strcmp(m2->part, m->part))
2060	      flag = 1;
2061	  if (!flag)
2062	  { if (typetable)
2063              for (p = typetable->list; p; p = p->next)
2064	        if ((m->mess&FAULT) && is_eq(m->part, p->info.typ->sym->name))
2065	          break;
2066	    if (!p && classtable)
2067              for (p = classtable->list; p; p = p->next)
2068	        if ((m->mess&FAULT) && is_eq(m->part, p->info.typ->id->name))
2069	          break;
2070            if (p)
2071            { fprintf(fd, "<message name=\"%sFault\">\n", ns_remove(m->part));
2072              fprintf(fd, " <part name=\"fault\" element=\"%s\"/>\n", ns_convert(m->part));
2073              fprintf(fd, "</message>\n\n");
2074	      flag = 0;
2075	      if (custom_fault)
2076	      { Table *r;
2077                r = entry(classtable, lookup("SOAP_ENV__Detail"))->info.typ->ref;
2078                if (r)
2079                  for (q = r->list; q; q = q->next)
2080	            if (!is_transient(q->info.typ) && !is_repetition(q) && !is_anytype(q) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun && (!strcmp(q->sym->name, m->part) || !strcmp(q->sym->name + 1, m->part)))
2081		    { flag = 1;
2082		      break;
2083	            }
2084	      }
2085	      if (!flag)
2086	      { sprintf(errbuf, "//gsoap %s method-fault %s %s directive does not refer to a member of struct SOAP_ENV__Detail: suggest to define struct SOAP_ENV__Detail with member %s", sp->ns, m->name, m->part, m->part);
2087                semwarn(errbuf);
2088	      }
2089	    }
2090	    else
2091            { sprintf(errbuf, "//gsoap %s method-fault %s %s directive does not refer to struct/class or typedef: should globablly define fault %s as type (typedef or struct/class)", sp->ns, m->name, m->part, m->part);
2092              semwarn(errbuf);
2093	    }
2094	  }
2095        }
2096      }
2097    }
2098    fflush(fd);
2099    if (sp && sp->porttype)
2100      fprintf(fd, "<portType name=\"%s\">\n", sp->porttype);
2101    else
2102      fprintf(fd, "<portType name=\"%s\">\n", ns_cname(name, "PortType"));
2103    for (p = t->list; p; p = p->next)
2104    { if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns, p->sym->name))
2105      { comment = NULL;
2106	if (sp)
2107	  for (m = sp->list; m; m = m->next)
2108	    if (m->mess == COMMENT && is_eq_nons(m->name, p->sym->name))
2109	      comment = m->part;
2110        fprintf(fd, " <operation name=\"%s\">\n", ns_remove(p->sym->name));
2111        if (comment)
2112          fprintf(fd, "  <documentation>%s</documentation>\n", comment);
2113        else
2114          fprintf(fd, "  <documentation>Service definition of function %s</documentation>\n", p->sym->name);
2115	if (get_response(p->info.typ))
2116          fprintf(fd, "  <input message=\"tns:%sRequest\"/>\n", ns_remove(p->sym->name));
2117	else
2118          fprintf(fd, "  <input message=\"tns:%s\"/>\n", ns_remove(p->sym->name));
2119	q = (Entry*)p->info.typ->ref;
2120	if (q && is_transient(q->info.typ))
2121	  ;
2122	else if (q && !is_response(q->info.typ))
2123	  fprintf(fd, "  <output message=\"tns:%sResponse\"/>\n", ns_remove(p->sym->name));
2124        else if (q)
2125	  fprintf(fd, "  <output message=\"tns:%s\"/>\n", ns_remove(((Tnode*)q->info.typ->ref)->id->name));
2126	if (sp)
2127	  for (m = sp->list; m; m = m->next)
2128	    if ((m->mess&FAULT) && is_eq_nons(m->name, p->sym->name))
2129	      fprintf(fd, "  <fault name=\"%s\" message=\"tns:%sFault\"/>\n", ns_remove(m->part), ns_remove(m->part));
2130        fprintf(fd, " </operation>\n");
2131      }
2132    }
2133    fprintf(fd, "</portType>\n\n");
2134    fprintf(fd, "<binding name=\"%s\" ", binding);
2135    if (is_document(style))
2136      if (sp && sp->porttype)
2137        fprintf(fd, "type=\"tns:%s\">\n <SOAP:binding style=\"document\"", sp->porttype);
2138      else
2139        fprintf(fd, "type=\"tns:%s\">\n <SOAP:binding style=\"document\"", ns_cname(name, "PortType"));
2140    else
2141      if (sp && sp->porttype)
2142        fprintf(fd, "type=\"tns:%s\">\n <SOAP:binding style=\"rpc\"", sp->porttype);
2143      else
2144        fprintf(fd, "type=\"tns:%s\">\n <SOAP:binding style=\"rpc\"", ns_cname(name, "PortType"));
2145    if (sp && sp->transport)
2146      fprintf(fd, " transport=\"%s\"/>\n", sp->transport);
2147    else
2148      fprintf(fd, " transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n");
2149    fflush(fd);
2150    for (p = t->list; p; p = p->next)
2151    { if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns, p->sym->name))
2152      { action = "";
2153	  mimein = 0;
2154	  mimeout = 0;
2155          method_style = style;
2156	  method_encoding = encoding;
2157	  method_response_encoding = NULL;
2158	  if (sp)
2159	  { for (m = sp->list; m; m = m->next)
2160	    { if (is_eq_nons(m->name, p->sym->name))
2161	      { if (m->mess&MIMEIN)
2162		  mimein = 1;
2163	        if (m->mess&MIMEOUT)
2164		  mimeout = 1;
2165                if (m->mess == ENCODING)
2166	          method_encoding = m->part;
2167                else if (m->mess == RESPONSE_ENCODING)
2168	          method_response_encoding = m->part;
2169                else if (m->mess == STYLE)
2170	          method_style = m->part;
2171	        else if (m->mess == ACTION)
2172	          action = m->part;
2173	      }
2174	    }
2175	  }
2176	if (!method_response_encoding)
2177	  method_response_encoding = method_encoding;
2178        fprintf(fd, " <operation name=\"%s\">\n", ns_remove(p->sym->name));
2179        if (is_document(style))
2180	{ if (is_document(method_style))
2181          { if (is_soap12(encoding) && !*action)
2182	      fprintf(fd, "  <SOAP:operation/>\n");
2183	    else if (*action == '"')
2184	      fprintf(fd, "  <SOAP:operation soapAction=%s/>\n", action);
2185            else
2186	      fprintf(fd, "  <SOAP:operation soapAction=\"%s\"/>\n", action);
2187	  }
2188	  else if (is_soap12(encoding) && !*action)
2189            fprintf(fd, "  <SOAP:operation style=\"rpc\"/>\n");
2190	  else if (*action == '"')
2191            fprintf(fd, "  <SOAP:operation style=\"rpc\" soapAction=%s/>\n", action);
2192          else
2193            fprintf(fd, "  <SOAP:operation style=\"rpc\" soapAction=\"%s\"/>\n", action);
2194	}
2195        else
2196	{ if (is_document(method_style))
2197          { if (is_soap12(encoding) && !*action)
2198	      fprintf(fd, "  <SOAP:operation style=\"document\"/>\n");
2199	    else if (*action == '"')
2200	      fprintf(fd, "  <SOAP:operation style=\"document\" soapAction=%s/>\n", action);
2201            else
2202	      fprintf(fd, "  <SOAP:operation style=\"document\" soapAction=\"%s\"/>\n", action);
2203	  }
2204	  else if (is_soap12(encoding) && !*action)
2205            fprintf(fd, "  <SOAP:operation style=\"rpc\"/>\n");
2206	  else if (*action == '"')
2207            fprintf(fd, "  <SOAP:operation style=\"rpc\" soapAction=%s/>\n", action);
2208          else
2209            fprintf(fd, "  <SOAP:operation style=\"rpc\" soapAction=\"%s\"/>\n", action);
2210	}
2211	fprintf(fd, "  <input>\n");
2212	if (mimein)
2213	  fprintf(fd, "   <MIME:multipartRelated>\n    <MIME:part>\n");
2214  	q = entry(classtable, p->sym);
2215  	if (is_literal(method_encoding) || (q && (q = (((Table*)q->info.typ->ref)->list)) && q && is_XML(q->info.typ)))
2216	{ if (is_document(method_style))
2217	    fprintf(fd, "     <SOAP:body parts=\"parameters\" use=\"literal\"/>\n");
2218          else
2219	    fprintf(fd, "     <SOAP:body parts=\"parameters\" use=\"literal\" namespace=\"%s\"/>\n", URI);
2220	}
2221        else
2222	{ if (encoding && *encoding)
2223	    fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, encoding);
2224          else if (method_encoding && *method_encoding)
2225	    fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, method_encoding);
2226          else
2227	    fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, encURI);
2228          if (!eflag)
2229          { sprintf(errbuf, "operation '%s' is not compliant with WS-I Basic Profile 1.0a, reason: uses SOAP encoding", p->sym->name);
2230            compliancewarn(errbuf);
2231	  }
2232	}
2233	if (custom_header)
2234	{ int f = 0;
2235	  m = NULL;
2236	  if (sp)
2237	    for (m = sp->list; m; m = m->next)
2238	      if (is_eq_nons(m->name, p->sym->name) && (m->mess&HDRIN))
2239	      { f = 1;
2240	        if (chkhdr(m->part))
2241	          fprintf(fd, "     <SOAP:header use=\"literal\" message=\"tns:%sHeader\" part=\"%s\"/>\n", name, ns_remove(m->part));
2242	      }
2243	}
2244	if (mimein)
2245	{ if (sp)
2246	  { for (m = sp->list; m; m = m->next)
2247	    { if (is_eq_nons(m->name, p->sym->name) && (m->mess&MIMEIN))
2248	        fprintf(fd, "    </MIME:part>\n    <MIME:part>\n     <MIME:content part=\"attachments\" type=\"%s\"/>\n", m->part);
2249	    }
2250	  }
2251	  fprintf(fd, "    </MIME:part>\n   </MIME:multipartRelated>\n");
2252	}
2253	fprintf(fd, "  </input>\n");
2254	q = (Entry*)p->info.typ->ref;
2255	if (!q || !q->info.typ->ref)
2256	{ fprintf(fd, " </operation>\n");
2257	  continue;
2258	}
2259	fprintf(fd, "  <output>\n");
2260	if (mimeout)
2261	  fprintf(fd, "   <MIME:multipartRelated>\n    <MIME:part>\n");
2262	if (is_literal(method_response_encoding) || is_XML(q->info.typ->ref))
2263	{ if (is_document(method_style))
2264	    fprintf(fd, "     <SOAP:body parts=\"parameters\" use=\"literal\"/>\n");
2265          else
2266	    fprintf(fd, "     <SOAP:body parts=\"parameters\" use=\"literal\" namespace=\"%s\"/>\n", URI);
2267	}
2268	else if (encoding && *encoding)
2269	  fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, encoding);
2270	else if (method_response_encoding && *method_response_encoding)
2271	  fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, method_response_encoding);
2272	else
2273	  fprintf(fd, "     <SOAP:body use=\"encoded\" namespace=\"%s\" encodingStyle=\"%s\"/>\n", URI, encURI);
2274	if (custom_header)
2275	{ int f = 0;
2276	  if (sp)
2277	    for (m = sp->list; m; m = m->next)
2278	      if (is_eq_nons(m->name, p->sym->name) && (m->mess&HDROUT))
2279	      { f = 1;
2280	        if (chkhdr(m->part))
2281	          fprintf(fd, "     <SOAP:header use=\"literal\" message=\"tns:%sHeader\" part=\"%s\"/>\n", name, ns_remove(m->part));
2282	      }
2283	}
2284	if (mimeout)
2285	{ if (sp)
2286	  { for (m = sp->list; m; m = m->next)
2287	    { if (is_eq_nons(m->name, p->sym->name) && (m->mess&MIMEOUT))
2288	        fprintf(fd, "    </MIME:part>\n    <MIME:part>\n     <MIME:content part=\"attachments\" type=\"%s\"/>\n", m->part);
2289	    }
2290	  }
2291	  fprintf(fd, "    </MIME:part>\n   </MIME:multipartRelated>\n");
2292	}
2293	fprintf(fd, "  </output>\n");
2294	if (sp)
2295	  for (m = sp->list; m; m = m->next)
2296	    if ((m->mess&FAULT) && is_eq_nons(m->name, p->sym->name))
2297	      fprintf(fd, "  <fault name=\"%s\">\n   <SOAP:fault name=\"%s\" use=\"literal\"/>\n  </fault>\n", ns_remove(m->part), ns_remove(m->part));
2298	fprintf(fd, " </operation>\n");
2299        fflush(fd);
2300      }
2301    }
2302    fprintf(fd, "</binding>\n\n");
2303  }
2304  fprintf(fd, "<service name=\"%s\">\n", name);
2305  if (sp && sp->documentation)
2306    fprintf(fd, " <documentation>%s</documentation>\n", sp->documentation);
2307  else
2308    fprintf(fd, " <documentation>gSOAP "VERSION" generated service definition</documentation>\n");
2309  if (executable)
2310    fprintf(fd, " <port name=\"%s\" binding=\"tns:%s\">\n  <SOAP:address location=\"%s/%s\"/>\n </port>\n</service>\n\n</definitions>\n", portname, binding, URL, executable);
2311  else
2312    fprintf(fd, " <port name=\"%s\" binding=\"tns:%s\">\n  <SOAP:address location=\"%s\"/>\n </port>\n</service>\n\n</definitions>\n", portname, binding, URL);
2313}
2314
2315char *
2316default_value(Entry *e, const char *a)
2317{ Entry *q;
2318  static char buf[1024];
2319  buf[0] = '\0';
2320  if (e->info.hasval)
2321    switch (e->info.typ->type)
2322    { case Tchar:
2323      case Twchar:
2324      case Tuchar:
2325      case Tshort:
2326      case Tushort:
2327      case Tint:
2328      case Tuint:
2329      case Tlong:
2330      case Tllong:
2331      case Tulong:
2332      case Tullong:
2333        sprintf(buf, " %s=\""SOAP_LONG_FORMAT"\"", a, e->info.val.i);
2334	break;
2335      case Tfloat:
2336      case Tdouble:
2337      case Tldouble:
2338        sprintf(buf, " %s=\"%f\"", a, e->info.val.r);
2339	break;
2340      case Ttime:
2341        break; /* should get value? */
2342      case Tenum:
2343	for (q = ((Table*)e->info.typ->ref)->list; q; q = q->next)
2344	  if (q->info.val.i == e->info.val.i)
2345	  { sprintf(buf, " %s=\"%s\"", a, ns_convert(q->sym->name));
2346	    break;
2347	  }
2348        break;
2349      default:
2350	if (e->info.val.s && strlen(e->info.val.s) < sizeof(buf)-12)
2351          sprintf(buf, " %s=\"%s\"", a, e->info.val.s);
2352	break;
2353    }
2354  return buf;
2355}
2356
2357const char *nillable(long minOccurs)
2358{ if (minOccurs)
2359    return "false";
2360  return "true";
2361}
2362
2363void
2364gen_schema(FILE *fd, Table *t, char *ns1, char *ns, int all, int wsdl, char *URL, char *URI, char *style, char *encoding)
2365{ int i, d;
2366  char cbuf[4];
2367  Entry *p, *q, *r;
2368  Tnode *n;
2369  Symbol *s;
2370  Service *sp, *sp2;
2371  Method *m;
2372  int flag;
2373  if (!strcmp(ns, "SOAP-ENV") || !strcmp(ns, "SOAP-ENC") || !strcmp(ns, "xsi") || !strcmp(ns, "xsd"))
2374    return;
2375  for (sp = services; sp; sp = sp->next)
2376    if (!tagcmp(sp->ns, ns) && sp->URI)
2377      break;
2378  if (sp && sp->import)
2379     return;
2380  fprintf(fd, " <schema ");
2381  if (sp)
2382    fprintf(fd, "targetNamespace=\"%s\"", sp->URI);
2383  else
2384    fprintf(fd, "targetNamespace=\"%s/%s.xsd\"", tmpURI, ns_convert(ns));
2385  for (s = nslist; s; s = s->next)
2386  { for (sp2 = services; sp2; sp2 = sp2->next)
2387      if (!tagcmp(sp2->ns, s->name) && sp2->URI)
2388        break;
2389    if (sp2)
2390      fprintf(fd, "\n  xmlns:%s=\"%s\"", ns_convert(s->name), sp2->URI);
2391    else if (!strcmp(s->name, "SOAP-ENV"))
2392      fprintf(fd, "\n  xmlns:SOAP-ENV=\"%s\"", envURI);
2393    else if (!strcmp(s->name, "SOAP-ENC"))
2394      fprintf(fd, "\n  xmlns:SOAP-ENC=\"%s\"", encURI);
2395    else if (!strcmp(s->name, "xsi"))
2396      fprintf(fd, "\n  xmlns:xsi=\"%s\"", xsiURI);
2397    else if (!strcmp(s->name, "xsd"))
2398      fprintf(fd, "\n  xmlns:xsd=\"%s\"", xsdURI);
2399    else
2400      fprintf(fd, "\n  xmlns:%s=\"%s/%s.xsd\"", ns_convert(s->name), tmpURI, ns_convert(s->name));
2401  }
2402  fprintf(fd, "\n  xmlns=\"%s\"\n", xsdURI);
2403  if (sp && (sp->elementForm || sp->attributeForm))
2404    fprintf(fd, "  elementFormDefault=\"%s\"\n  attributeFormDefault=\"%s\">\n", sp->elementForm?sp->elementForm:"unqualified", sp->attributeForm?sp->attributeForm:"unqualified");
2405  else if (style && !strcmp(style, "document"))
2406    fprintf(fd, "  elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n");
2407  else
2408    fprintf(fd, "  elementFormDefault=\"unqualified\"\n  attributeFormDefault=\"unqualified\">\n");
2409  fflush(fd);
2410  flag = 0;
2411  for (s = nslist; s; s = s->next)
2412  { for (sp2 = services; sp2; sp2 = sp2->next)
2413      if (!tagcmp(sp2->ns, s->name) && sp2->import && sp2->URI)
2414        break;
2415    if (sp2)
2416    { fprintf(fd, "  <import namespace=\"%s\"", sp2->URI);
2417      if (sp2->import && sp2->import != sp2->URI)
2418        fprintf(fd, " schemaLocation=\"%s\"", sp2->import);
2419      fprintf(fd, "/>\n");
2420      if (!strcmp(sp2->URI, encURI))
2421        flag = 1;
2422    }
2423  }
2424  if (!flag)
2425    fprintf(fd, "  <import namespace=\"%s\"/>", encURI);
2426  fprintf(fd, "\n");
2427  fflush(fd);
2428  if (typetable)
2429  { for (p = typetable->list; p; p = p->next)
2430    { if (p->info.typ->type != Ttemplate && !is_transient(p->info.typ) && !is_invisible(p->sym->name) && (!is_external(p->info.typ) || is_volatile(p->info.typ)) && ((has_ns_eq(ns, p->sym->name))))
2431      { /* typedefs that are used for SOAP Fault details */
2432        m = NULL;
2433	if (p->info.typ->type != Tstruct && p->info.typ->type != Tclass)
2434        { for (sp2 = services; sp2 && !m; sp2 = sp2->next)
2435	  { for (m = sp2->list; m; m = m->next)
2436	    { if ((m->mess&FAULT) && m->part && is_eq(m->part, p->sym->name))
2437	        break;
2438	    }
2439	  }
2440	}
2441        if (m)
2442        { fprintf(fd, "  <!-- fault element -->\n");
2443          fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(p->sym->name), base_type(p->info.typ, ns1));
2444          continue;
2445        }
2446        if (is_primitive_or_string(p->info.typ) || (p->info.typ->type == Tpointer && is_primitive_or_string(p->info.typ->ref)))
2447	{ fprintf(fd, "  <simpleType name=\"%s\">", ns_remove(p->sym->name));
2448          gen_type_documentation(fd, t, p, ns, ns1);
2449	  fprintf(fd, "   <restriction base=\"%s\">\n", base_type(p->info.typ, ns1));
2450	  if (p->info.typ->pattern)
2451            fprintf(fd, "    <pattern value=\"%s\"/>\n", p->info.typ->pattern);
2452          if (is_primitive(p->info.typ) || (p->info.typ->type == Tpointer && is_primitive(p->info.typ->ref) && !is_string(p->info.typ) && !is_wstring(p->info.typ)))
2453	  { if (p->info.typ->minLength != -1)
2454              fprintf(fd, "    <minInclusive value=\"%ld\"/>\n", p->info.typ->minLength);
2455	    if (p->info.typ->maxLength != -1)
2456              fprintf(fd, "    <maxInclusive value=\"%ld\"/>\n", p->info.typ->maxLength);
2457	  }
2458	  else
2459	  { if (p->info.typ->maxLength > 0 && p->info.typ->minLength == p->info.typ->maxLength)
2460              fprintf(fd, "    <length value=\"%ld\"/>\n", p->info.typ->minLength);
2461	    else
2462	    { if (p->info.typ->minLength > 0)
2463                fprintf(fd, "    <minLength value=\"%ld\"/>\n", p->info.typ->minLength);
2464	      if (p->info.typ->maxLength > 0)
2465                fprintf(fd, "    <maxLength value=\"%ld\"/>\n", p->info.typ->maxLength);
2466	    }
2467	  }
2468          fprintf(fd, "   </restriction>\n  </simpleType>\n");
2469        }
2470        else
2471	{ fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2472	  gen_type_documentation(fd, t, p, ns, ns1);
2473	  fprintf(fd, "   <complexContent>\n    <restriction base=\"%s\">\n", base_type(p->info.typ, ns1));
2474          fprintf(fd, "    </restriction>\n   </complexContent>\n  </complexType>\n");
2475        }
2476      }
2477    }
2478  }
2479  fflush(fd);
2480  if (enumtable)
2481  { for (p = enumtable->list; p; p = p->next)
2482    { if (!is_transient(p->info.typ) && !is_invisible(p->sym->name) && ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name)))
2483      { if (is_mask(p->info.typ))
2484        { fprintf(fd, "  <simpleType name=\"%s\">", wsdl_type(p->info.typ, NULL));
2485          gen_type_documentation(fd, t, p, ns, ns1);
2486          fprintf(fd, "   <list>\n");
2487	  q = p;
2488	  if ((Table*)p->info.typ->ref)
2489	  { for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
2490	      if (!has_ns_eq(NULL, ns_remove1(((Table*)p->info.typ->ref)->list->sym->name)))
2491	        break;
2492	  }
2493	  if (q)
2494            fprintf(fd, "    <restriction base=\"xsd:string\">\n");
2495	  else
2496            fprintf(fd, "    <restriction base=\"xsd:QName\">\n");
2497          if ((Table*)p->info.typ->ref)
2498            for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
2499              fprintf(fd, "     <enumeration value=\"%s\"/><!-- enum const = "SOAP_LONG_FORMAT" -->\n", ns_remove2(q->sym->name), q->info.val.i);
2500          fprintf(fd, "    </restriction>\n   </list>\n  </simpleType>\n");
2501	}
2502	else
2503	{ fprintf(fd, "  <simpleType name=\"%s\">", wsdl_type(p->info.typ, NULL));
2504          gen_type_documentation(fd, t, p, ns, ns1);
2505	  q = p;
2506	  if ((Table*)p->info.typ->ref)
2507	  { for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
2508	      if (!has_ns_eq(NULL, ns_remove1(((Table*)p->info.typ->ref)->list->sym->name)))
2509	        break;
2510	  }
2511	  if (q)
2512	    fprintf(fd, "   <restriction base=\"xsd:string\">\n");
2513	  else
2514            fprintf(fd, "   <restriction base=\"xsd:QName\">\n");
2515          if ((Table*)p->info.typ->ref)
2516            for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
2517              fprintf(fd, "    <enumeration value=\"%s\"/><!-- enum const = "SOAP_LONG_FORMAT" -->\n", ns_remove2(q->sym->name), q->info.val.i);
2518          fprintf(fd, "   </restriction>\n  </simpleType>\n");
2519        }
2520      }
2521    }
2522  }
2523  fflush(fd);
2524  if (classtable)
2525  { for (p = classtable->list; p; p = p->next)
2526    { if (is_transient(p->info.typ) || is_invisible(p->sym->name))
2527        continue;
2528      for (q = t->list; q; q = q->next)
2529        if (q->info.typ->type == Tfun && !(q->info.sto & Sextern) && p == get_response(q->info.typ))
2530	  break;
2531      /* omit the auto-generated and user-defined response struct/class (when necessary) */
2532      if (!q)
2533        for (q = t->list; q; q = q->next)
2534          if (q->info.typ->type == Tfun && !(q->info.sto & Sextern) && !has_ns_eq(NULL, ((Entry*)q->info.typ->ref)->sym->name))
2535          { r = entry(t, q->sym);
2536            if (r && r->info.typ->ref && is_response(((Entry*)r->info.typ->ref)->info.typ) && p->info.typ == ((Entry*)r->info.typ->ref)->info.typ->ref)
2537              break;
2538	  }
2539      if (q)
2540        continue;
2541      /* classes that are used for SOAP Fault details */
2542      m = NULL;
2543      for (sp2 = services; sp2 && !m; sp2 = sp2->next)
2544	for (m = sp2->list; m; m = m->next)
2545	  if ((m->mess&FAULT) && m->part && is_eq(m->part, p->sym->name))
2546	    break;
2547      if (m)
2548      { if ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name))
2549        { fprintf(fd, "  <!-- fault element and type -->\n");
2550          fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(p->sym->name), base_type(p->info.typ, ns1));
2551	}
2552      }
2553      if (p->info.typ->ref && is_binary(p->info.typ))
2554      { if ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name))
2555	{ if (is_attachment(p->info.typ))
2556	  { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2557	    gen_type_documentation(fd, t, p, ns, ns1);
2558	    fprintf(fd, "   <simpleContent>\n    <extension base=\"xsd:base64Binary\">\n");
2559	    if (!eflag)
2560              fprintf(fd, "     <attribute name=\"href\" type=\"xsd:anyURI\" use=\"optional\"/>\n");
2561	    gen_schema_attributes(fd, p->info.typ, ns, ns1);
2562            fprintf(fd, "    </extension>\n   </simpleContent>\n  </complexType>\n");
2563	  }
2564	  else
2565	  { fprintf(fd, "  <simpleType name=\"%s\">", ns_remove(p->sym->name));
2566	    gen_type_documentation(fd, t, p, ns, ns1);
2567	    fprintf(fd, "   <restriction base=\"xsd:base64Binary\">\n");
2568	    if (p->info.typ->maxLength > 0 && p->info.typ->minLength == p->info.typ->maxLength)
2569              fprintf(fd, "    <length value=\"%ld\"/>\n", p->info.typ->minLength);
2570	    else
2571	    { if (p->info.typ->minLength > 0)
2572                fprintf(fd, "    <minLength value=\"%ld\"/>\n", p->info.typ->minLength);
2573	      if (p->info.typ->maxLength > 0)
2574                fprintf(fd, "    <maxLength value=\"%ld\"/>\n", p->info.typ->maxLength);
2575	    }
2576            fprintf(fd, "   </restriction>\n  </simpleType>\n");
2577	  }
2578        }
2579      }
2580      else if (p->info.typ->ref && !is_transient(p->info.typ) && is_primclass(p->info.typ))
2581      { if ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name))
2582        { q = ((Table*)p->info.typ->ref)->list;
2583	  if (q && strncmp(q->sym->name, "xsd__anyType", 12))
2584	  { if (is_string(q->info.typ) || is_wstring(q->info.typ) || is_stdstring(q->info.typ) || is_stdwstring(q->info.typ))
2585            { fprintf(fd, "  <complexType name=\"%s\" mixed=\"true\">", ns_remove(p->sym->name));
2586	      gen_type_documentation(fd, t, p, ns, ns1);
2587              fprintf(fd, "   <simpleContent>\n    <extension base=\"%s\">\n", wsdl_type(q->info.typ, ns1));
2588	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2589              fprintf(fd, "    </extension>\n   </simpleContent>\n  </complexType>\n");
2590	    }
2591	    else if (is_primitive(q->info.typ))
2592            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2593	      gen_type_documentation(fd, t, p, ns, ns1);
2594              fprintf(fd, "   <simpleContent>\n    <extension base=\"%s\">\n", wsdl_type(q->info.typ, ns1));
2595	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2596              fprintf(fd, "    </extension>\n   </simpleContent>\n  </complexType>\n");
2597	    }
2598	    else
2599            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2600	      gen_type_documentation(fd, t, p, ns, ns1);
2601              fprintf(fd, "   <complexContent>\n    <extension base=\"%s\">\n", wsdl_type(q->info.typ, ns1));
2602	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2603              fprintf(fd, "    </extension>\n   </complexContent>\n  </complexType>\n");
2604	    }
2605	  }
2606        }
2607      }
2608      else if (p->info.typ->ref && !is_transient(p->info.typ))
2609      { q = ((Table*)p->info.typ->ref)->list;
2610        if (entry(t, p->sym) && (!q || !is_XML(q->info.typ)))
2611          ;
2612        else if (is_dynamic_array(p->info.typ))
2613        { if (eflag || (!has_ns(p->info.typ) && !is_untyped(p->info.typ)))
2614          { if (all)
2615	      { d = get_Darraydims(p->info.typ)-1;
2616	        for (i = 0; i < d; i++)
2617	          cbuf[i] = ',';
2618	        cbuf[i] = '\0';
2619		if (q->info.maxOccurs == 1)
2620	          fprintf(fd, "  <complexType name=\"%s\">\n   <complexContent>\n    <restriction base=\"SOAP-ENC:Array\">\n     <sequence>\n      <element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </sequence>\n     <attribute ref=\"SOAP-ENC:arrayType\" WSDL:arrayType=\"%s[%s]\"/>\n    </restriction>\n   </complexContent>\n  </complexType>\n", wsdl_type(p->info.typ, NULL), q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1), wsdl_type(q->info.typ, ns1), cbuf);
2621                else
2622	          fprintf(fd, "  <complexType name=\"%s\">\n   <complexContent>\n    <restriction base=\"SOAP-ENC:Array\">\n     <sequence>\n      <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n     </sequence>\n     <attribute ref=\"SOAP-ENC:arrayType\" WSDL:arrayType=\"%s[%s]\"/>\n    </restriction>\n   </complexContent>\n  </complexType>\n", wsdl_type(p->info.typ, NULL), q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1), q->info.minOccurs, q->info.maxOccurs, wsdl_type(q->info.typ, ns1), cbuf);
2623	    }
2624          }
2625	  else if (p->info.typ->ref && ((Table*)p->info.typ->ref)->prev && !is_transient(entry(classtable, ((Table*)p->info.typ->ref)->prev->sym)->info.typ) && strncmp(((Table*)p->info.typ->ref)->prev->sym->name, "xsd__anyType", 12))
2626	  { if (q->info.maxOccurs == 1)
2627            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2628	      gen_type_documentation(fd, t, p, ns, ns1);
2629              fprintf(fd, "   <complexContent>\n    <extension base=\"%s\">\n     <sequence>\n", ns_convert(((Table*)p->info.typ->ref)->prev->sym->name));
2630	      fprintf(fd, "      <element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\" nillable=\"true\"/>\n", q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1));
2631              fprintf(fd, "     </sequence>\n    </extension>\n   </complexContent>\n");
2632	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2633              fprintf(fd, "  </complexType>\n");
2634	    }
2635	    else
2636            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2637	      gen_type_documentation(fd, t, p, ns, ns1);
2638              fprintf(fd, "   <complexContent>\n    <extension base=\"%s\">\n     <sequence>\n", ns_convert(((Table*)p->info.typ->ref)->prev->sym->name));
2639	      fprintf(fd, "      <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"/>\n", q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs));
2640              fprintf(fd, "     </sequence>\n    </extension>\n   </complexContent>\n");
2641	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2642              fprintf(fd, "  </complexType>\n");
2643	    }
2644	  }
2645	  else
2646	  { if (q->info.maxOccurs == 1)
2647	    { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2648	      gen_type_documentation(fd, t, p, ns, ns1);
2649	      fprintf(fd, "   <sequence>\n    <element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\" nillable=\"true\"/>\n   </sequence>\n  </complexType>\n", q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1));
2650	    }
2651            else
2652	    { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2653	      gen_type_documentation(fd, t, p, ns, ns1);
2654	      fprintf(fd, "   <sequence>\n    <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"/>\n   </sequence>\n  </complexType>\n", q->sym->name[5]?ns_remove(q->sym->name+5):"item", wsdl_type(q->info.typ, ns1), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs));
2655	    }
2656	  }
2657	}
2658        else if (is_discriminant(p->info.typ) && ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name)))
2659        { if (p->info.typ->ref)
2660          { fprintf(fd, "  <complexType name=\"%s\">\n", ns_remove(p->sym->name));
2661	    gen_schema_elements(fd, p->info.typ, ns, ns1);
2662            fprintf(fd, "  </complexType>\n");
2663	  }
2664        }
2665        else if (p->info.typ->type == Tstruct && ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name)))
2666        { if (p->info.typ->ref)
2667          { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2668	    gen_type_documentation(fd, t, p, ns, ns1);
2669            fprintf(fd, "   <sequence>\n");
2670	    gen_schema_elements(fd, p->info.typ, ns, ns1);
2671            fprintf(fd, "   </sequence>\n");
2672	    gen_schema_attributes(fd, p->info.typ, ns, ns1);
2673            fprintf(fd, "  </complexType>\n");
2674          }
2675        }
2676        else if (p->info.typ->type == Tclass && ((!has_ns(p->info.typ) && all) || has_ns_eq(ns, p->sym->name)))
2677        { if (p->info.typ->ref)
2678          { if (((Table*)p->info.typ->ref)->prev && !is_transient(entry(classtable, ((Table*)p->info.typ->ref)->prev->sym)->info.typ) && strncmp(((Table*)p->info.typ->ref)->prev->sym->name, "xsd__anyType", 12))
2679            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2680	      gen_type_documentation(fd, t, p, ns, ns1);
2681              fprintf(fd, "   <complexContent>\n    <extension base=\"%s\">\n     <sequence>\n", ns_convert(((Table*)p->info.typ->ref)->prev->sym->name));
2682	      gen_schema_elements(fd, p->info.typ, ns, ns1);
2683              fprintf(fd, "     </sequence>\n    </extension>\n   </complexContent>\n");
2684	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2685              fprintf(fd, "  </complexType>\n");
2686	    }
2687	    else
2688            { fprintf(fd, "  <complexType name=\"%s\">", ns_remove(p->sym->name));
2689	      gen_type_documentation(fd, t, p, ns, ns1);
2690              fprintf(fd, "   <sequence>\n");
2691	      gen_schema_elements(fd, p->info.typ, ns, ns1);
2692              fprintf(fd, "   </sequence>\n");
2693	      gen_schema_attributes(fd, p->info.typ, ns, ns1);
2694              fprintf(fd, "  </complexType>\n");
2695            }
2696	  }
2697        }
2698      }
2699    }
2700  }
2701  fflush(fd);
2702  for (n = Tptr[Tarray]; n; n = n->next)
2703  { if (is_transient(n))
2704      continue;
2705    else if (1 /* wsdl */)
2706      fprintf(fd, "  <complexType name=\"%s\">\n   <complexContent>\n    <restriction base=\"SOAP-ENC:Array\">\n     <attribute ref=\"SOAP-ENC:arrayType\" WSDL:arrayType=\"%s[]\"/>\n    </restriction>\n   </complexContent>\n  </complexType>\n", c_ident(n), wsdl_type(n->ref, ns1));
2707    else
2708      fprintf(fd, "  <complexType name=\"%s\">\n   <complexContent>\n    <restriction base=\"SOAP-ENC:Array\">\n     <element name=\"item\" type=\"%s\" maxOccurs=\"unbounded\"/>\n    </restriction>\n   </complexContent>\n  </complexType>\n", c_ident(n), xsi_type(n->ref));
2709    fflush(fd);
2710  }
2711  gen_schema_elements_attributes(fd, t, ns, ns1, style, encoding);
2712  fprintf(fd, " </schema>\n\n");
2713}
2714
2715void
2716gen_schema_elements(FILE *fd, Tnode *p, char *ns, char *ns1)
2717{ Entry *q;
2718  for (q = ((Table*)p->ref)->list; q; q = q->next)
2719    if (gen_schema_element(fd, q, ns, ns1))
2720      q = q->next;
2721}
2722
2723int
2724gen_schema_element(FILE *fd, Entry *q, char *ns, char *ns1)
2725{ char *s, *t;
2726      if (is_transient(q->info.typ) || (q->info.sto & Sattribute) || q->info.typ->type == Tfun || q->info.typ->type == Tunion)
2727        return 0;
2728      if (is_repetition(q))
2729      { if (is_sequence(q->next))
2730        { fprintf(fd, "    <sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n");
2731	  if (q->next->info.typ->ref)
2732	    gen_schema_elements(fd, q->next->info.typ->ref, ns, ns1);
2733          fprintf(fd, "    </sequence>\n");
2734          return 1;
2735        }
2736        t = ns_convert(q->next->sym->name);
2737        if (*t == '-')
2738	  fprintf(fd, "     <any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/><!-- member %s -->\n", q->next->sym->name);
2739        else if ((s = strchr(t, ':'))) /* && !has_ns_eq(ns, q->next->sym->name)) */
2740	{ if (((Tnode*)q->next->info.typ->ref)->type == Tpointer)
2741            if (q->info.maxOccurs == 1)
2742	      fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", t, q->info.minOccurs);
2743            else
2744	      fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2745            else
2746          if (q->info.maxOccurs == 1)
2747              fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", t, q->info.minOccurs);
2748	    else
2749              fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2750	}
2751	else
2752	{ if (s) s++; else s = t;
2753	  if (((Tnode*)q->next->info.typ->ref)->type == Tpointer)
2754            if (q->info.maxOccurs == 1)
2755	      fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\" nillable=\"%s\"/>\n", s, wsdl_type(q->next->info.typ->ref, ns1), q->info.minOccurs, nillable(q->info.minOccurs));
2756            else
2757	      fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"/>\n", s, wsdl_type(q->next->info.typ->ref, ns1), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs));
2758          else
2759            if (q->info.maxOccurs == 1)
2760              fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", s, wsdl_type(q->next->info.typ->ref, ns1), q->info.minOccurs);
2761	    else
2762              fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", s, wsdl_type(q->next->info.typ->ref, ns1), q->info.minOccurs, q->info.maxOccurs);
2763	}
2764        return 1;
2765      }
2766      else if (q->info.typ->type == Ttemplate || (q->info.typ->type == Tpointer && ((Tnode*)q->info.typ->ref)->type == Ttemplate) || (q->info.typ->type == Treference && ((Tnode*)q->info.typ->ref)->type == Ttemplate))
2767      { t = ns_convert(q->sym->name);
2768        if (*t == '-')
2769	  fprintf(fd, "     <any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/><!-- member %s -->\n", q->sym->name);
2770        else if ((s = strchr(t, ':'))) /* && !has_ns_eq(ns, q->sym->name)) */
2771	{ if (((Tnode*)q->info.typ->ref)->type == Tpointer)
2772            if (q->info.maxOccurs == 1)
2773	      fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", t, q->info.minOccurs);
2774            else
2775	      fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2776            else
2777          if (q->info.maxOccurs == 1)
2778              fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", t, q->info.minOccurs);
2779	    else
2780              fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2781	}
2782	else
2783	{ if (s) s++; else s = t;
2784	  if (((Tnode*)q->info.typ->ref)->type == Tpointer)
2785            if (q->info.maxOccurs == 1)
2786	      fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\" nillable=\"%s\"/>\n", s, wsdl_type(q->info.typ->ref, ns1), q->info.minOccurs, nillable(q->info.minOccurs));
2787            else
2788	      fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"/>\n", s, wsdl_type(q->info.typ->ref, ns1), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs));
2789          else
2790            if (q->info.maxOccurs == 1)
2791              fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"unbounded\"/>\n", s, wsdl_type(q->info.typ->ref, ns1), q->info.minOccurs);
2792	    else
2793              fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", s, wsdl_type(q->info.typ->ref, ns1), q->info.minOccurs, q->info.maxOccurs);
2794	}
2795      }
2796      else if (is_anytype(q)) /* ... maybe need to show all possible types rather than xsd:anyType */
2797      { fprintf(fd, "     <element name=\"%s\" type=\"xsd:anyType\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"/>\n", ns_convert(q->next->sym->name), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs));
2798        return 1;
2799      }
2800      else if (is_choice(q))
2801      { if (q->info.minOccurs == 0)
2802          fprintf(fd, "    <choice minOccurs=\"0\" maxOccurs=\"1\">\n");
2803        else
2804          fprintf(fd, "    <choice>\n");
2805	if (q->next->info.typ->ref)
2806	  gen_schema_elements(fd, q->next->info.typ, ns, ns1);
2807        fprintf(fd, "    </choice>\n");
2808        return 1;
2809      }
2810      else if (is_sequence(q))
2811      { if (q->info.minOccurs == 0)
2812          fprintf(fd, "    <sequence minOccurs=\"0\" maxOccurs=\"1\">\n");
2813        else
2814          fprintf(fd, "    <sequence>\n");
2815	if (q->info.typ->type == Tpointer)
2816	  gen_schema_elements(fd, q->info.typ->ref, ns, ns1);
2817	else if (q->info.typ->ref)
2818	  gen_schema_elements(fd, q->info.typ, ns, ns1);
2819        fprintf(fd, "    </sequence>\n");
2820        return 0;
2821      }
2822      else
2823      { t = ns_convert(q->sym->name);
2824        if (*t == '-')
2825	  fprintf(fd, "     <any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"1\"/><!-- member %s -->\n", q->sym->name);
2826        else if ((s = strchr(t, ':'))) /* && !has_ns_eq(ns, q->sym->name)) */
2827	{ if (q->info.typ->type == Tpointer || q->info.typ->type == Tarray || is_dynamic_array(q->info.typ))
2828            fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2829          else
2830            fprintf(fd, "     <element ref=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"/>\n", t, q->info.minOccurs, q->info.maxOccurs);
2831	}
2832        else
2833	{ if (s) s++; else s = t;
2834	  if (q->info.typ->type == Tpointer || q->info.typ->type == Tarray || is_dynamic_array(q->info.typ))
2835            fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\" nillable=\"%s\"%s/>\n", s, wsdl_type(q->info.typ, ns1), q->info.minOccurs, q->info.maxOccurs, nillable(q->info.minOccurs), default_value(q, "default"));
2836          else
2837            fprintf(fd, "     <element name=\"%s\" type=\"%s\" minOccurs=\"%ld\" maxOccurs=\"%ld\"%s/>\n", s, wsdl_type(q->info.typ, ns1), q->info.minOccurs, q->info.maxOccurs, default_value(q, "default"));
2838        }
2839      }
2840      fflush(fd);
2841  return 0;
2842}
2843
2844void
2845gen_schema_elements_attributes(FILE *fd, Table *t, char *ns, char *ns1, char *style, char *encoding)
2846{ Entry *p, *q, *e;
2847  Table *r;
2848  Service *sp;
2849  Method *m;
2850  char *method_style, *method_encoding, *method_response_encoding;
2851  int all = !strcmp(ns, ns1);
2852  r = mktable(NULL);
2853  for (p = classtable->list; p; p = p->next)
2854  { if (!p->info.typ->ref || /* is_invisible(p->info.typ->id->name) || */ is_transient(p->info.typ) || is_primclass(p->info.typ) || is_dynamic_array(p->info.typ))
2855      continue;
2856    for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
2857    { if (!is_repetition(q) && !is_anytype(q) && has_ns_eq(ns, q->sym->name) && !is_transient(q->info.typ) && q->info.typ->type != Tfun)
2858      { Service *sp2;
2859        Method *m;
2860        m = NULL;
2861        for (sp2 = services; sp2 && !m; sp2 = sp2->next)
2862	  for (m = sp2->list; m; m = m->next)
2863	    if ((m->mess&FAULT) && m->part && is_eq(m->part, q->sym->name))
2864	      break;
2865	if (m)
2866	  continue; /* already generated element for fault */
2867        e = entry(r, q->sym);
2868        if (e)
2869	{ if ((e->info.sto & Sattribute) != (q->info.sto & Sattribute) || reftype(e->info.typ) != reftype(q->info.typ))
2870          { sprintf(errbuf, "Field '%s' of type '%s' at line %d has a type that does not correspond to the required unique type '%s' defined for elements '<%s>' in the WSDL namespace based on literal encoding: use SOAP RPC encoding or rename or use a namespace qualifier", q->sym->name, c_type(q->info.typ), q->lineno, c_type(e->info.typ), ns_convert(q->sym->name));
2871            semwarn(errbuf);
2872	  }
2873	}
2874        else
2875	{ if (q->info.sto & Sattribute)
2876	    fprintf(fd, "  <attribute name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
2877	  else
2878	    fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
2879	  e = enter(r, q->sym);
2880	  e->info = q->info;
2881        }
2882      }
2883    }
2884  }
2885  if (t && all)
2886  { for (p = t->list; p; p = p->next)
2887    { if (p->info.typ->type == Tfun && !is_invisible(p->sym->name) && !(p->info.sto & Sextern) && has_ns_eq(ns, p->sym->name))
2888      { method_encoding = encoding;
2889	method_response_encoding = NULL;
2890	method_style = style;
2891	for (sp = services; sp; sp = sp->next)
2892	{ if (!tagcmp(sp->ns, ns))
2893	  { for (m = sp->list; m; m = m->next)
2894	    { if (is_eq_nons(m->name, p->sym->name))
2895              { if (m->mess == ENCODING)
2896	          method_encoding = m->part;
2897                else if (m->mess == RESPONSE_ENCODING)
2898	          method_response_encoding = m->part;
2899                else if (m->mess == STYLE)
2900	          method_style = m->part;
2901	      }
2902	    }
2903	  }
2904	}
2905	if (!eflag)
2906	{ if (!method_response_encoding)
2907            method_response_encoding = method_encoding;
2908          q = entry(classtable, p->sym);
2909          if (q)
2910	  { if (is_document(method_style))
2911            { fprintf(fd, "  <!-- operation request element -->\n");
2912	      fprintf(fd, "  <element name=\"%s\">\n   <complexType>\n    <sequence>\n", ns_remove(p->sym->name));
2913	      gen_schema_elements(fd, q->info.typ, ns, ns1);
2914	      fprintf(fd, "    </sequence>\n");
2915	      gen_schema_attributes(fd, q->info.typ, ns, ns1);
2916	      fprintf(fd, "   </complexType>\n  </element>\n");
2917	    }
2918	    else if (is_literal(method_encoding))
2919	    { for (q = ((Table*)q->info.typ->ref)->list; q; q = q->next)
2920              { if (!is_repetition(q) && !is_anytype(q) && !has_ns_eq(NULL, q->sym->name) && !is_transient(q->info.typ) && q->info.typ->type != Tfun && !(q->info.sto & Sattribute))
2921                { e = entry(r, q->sym);
2922                  if (e)
2923	          { if ((e->info.sto & Sattribute) != (q->info.sto & Sattribute)|| reftype(e->info.typ) != reftype(q->info.typ))
2924                    { sprintf(errbuf, "Parameter '%s' of type '%s' at line %d has a type that does not correspond to the required unique type '%s' defined for elements '<%s>' in the WSDL namespace based on literal encoding: use SOAP RPC encoding or rename or use a namespace qualifier", q->sym->name, c_type(q->info.typ), q->lineno, c_type(e->info.typ), ns_convert(q->sym->name));
2925                      semwarn(errbuf);
2926	            }
2927	          }
2928                  else
2929                  { fprintf(fd, "  <!-- operation request element -->\n");
2930	            fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
2931	            e = enter(r, q->sym);
2932		    e->info = q->info;
2933	          }
2934	        }
2935	      }
2936	    }
2937            q = (Entry*)p->info.typ->ref;
2938            for (e = t->list; e; e = e->next)
2939              if (e != p && e->info.typ->type == Tfun && !(e->info.sto & Sextern) && q == e->info.typ->ref)
2940	        q = NULL;
2941            if (q && !is_transient(q->info.typ))
2942            { if (!is_response(q->info.typ))
2943	      { if (is_document(method_style))
2944                { fprintf(fd, "  <!-- operation response element -->\n");
2945	          fprintf(fd, "  <element name=\"%sResponse\">\n   <complexType>\n    <sequence>\n", ns_remove(p->sym->name));
2946	          gen_schema_element(fd, q, ns, ns1);
2947	          fprintf(fd, "    </sequence>\n");
2948	          fprintf(fd, "   </complexType>\n  </element>\n");
2949		}
2950  	        else if (is_literal(method_response_encoding))
2951                { e = entry(r, q->sym);
2952                  if (e)
2953	          { if ((e->info.sto & Sattribute) != (q->info.sto & Sattribute)|| reftype(e->info.typ) != reftype(q->info.typ))
2954                    { sprintf(errbuf, "Qualified field '%s' has a type that does not correspond to the unique type '%s' defined for elements '<%s>'", q->sym->name, c_type(q->info.typ), ns_convert(q->sym->name));
2955                      semwarn(errbuf);
2956	            }
2957	          }
2958                  else
2959                  { fprintf(fd, "  <!-- operation response element -->\n");
2960	            fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
2961	            e = enter(r, q->sym);
2962		    e->info = q->info;
2963	          }
2964	        }
2965	      }
2966              else if (((Tnode*)q->info.typ->ref)->ref)
2967	      { if (is_document(method_style))
2968	        { if (!has_ns_eq(NULL, q->sym->name))
2969		  { e = entry(r, ((Tnode*)q->info.typ->ref)->id);
2970		    if (!e)
2971                    { fprintf(fd, "  <!-- operation response element -->\n");
2972		      fprintf(fd, "  <element name=\"%s\">\n   <complexType>\n    <sequence>\n", ns_remove(((Tnode*)q->info.typ->ref)->id->name));
2973	              gen_schema_elements(fd, q->info.typ->ref, ns, ns1);
2974	              fprintf(fd, "    </sequence>\n");
2975	              gen_schema_attributes(fd, q->info.typ->ref, ns, ns1);
2976	              fprintf(fd, "   </complexType>\n  </element>\n");
2977		      e = enter(r, ((Tnode*)q->info.typ->ref)->id);
2978		      e->info = q->info;
2979		    }
2980		  }
2981		}
2982		else if (is_literal(method_response_encoding))
2983	        { for (q = ((Table*)((Tnode*)q->info.typ->ref)->ref)->list; q; q = q->next)
2984  	          { if (!is_repetition(q) && !is_anytype(q) && !has_ns_eq(NULL, q->sym->name) && !is_transient(q->info.typ) && q->info.typ->type != Tfun && !(q->info.sto & Sattribute))
2985                    { e = entry(r, q->sym);
2986                      if (e)
2987	              { if ((e->info.sto & Sattribute) != (q->info.sto & Sattribute)|| reftype(e->info.typ) != reftype(q->info.typ))
2988                        { sprintf(errbuf, "Qualified field '%s' has a type that does not correspond to the unique type '%s' defined for elements '<%s>'", q->sym->name, c_type(q->info.typ), ns_convert(q->sym->name));
2989                          semwarn(errbuf);
2990	                }
2991	              }
2992                      else
2993                      { fprintf(fd, "  <!-- operation response element -->\n");
2994	                fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
2995	                e = enter(r, q->sym);
2996		        e->info = q->info;
2997	              }
2998	            }
2999	          }
3000	        }
3001	      }
3002            }
3003          }
3004        }
3005      }
3006    }
3007  }
3008  if (t)
3009  { for (p = t->list; p; p = p->next)
3010    { if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && !eflag)
3011      { q = (Entry*)p->info.typ->ref;
3012        if (q && !is_transient(q->info.typ))
3013        { if (is_response(q->info.typ))
3014	  { if (has_ns_eq(ns, q->sym->name))
3015            { e = entry(r, q->sym);
3016              if (!e)
3017              { fprintf(fd, "  <!-- operation response element -->\n");
3018	        fprintf(fd, "  <element name=\"%s\" type=\"%s\"/>\n", ns_remove(q->sym->name), wsdl_type(q->info.typ, ns1));
3019	        e = enter(r, q->sym);
3020		e->info = q->info;
3021	      }
3022	    }
3023	  }
3024        }
3025      }
3026    }
3027  }
3028  freetable(r);
3029}
3030
3031void
3032gen_schema_attributes(FILE *fd, Tnode *p, char *ns, char *ns1)
3033{ Entry *q;
3034  char *t, *s, *r;
3035  for (q = ((Table*)p->ref)->list; q; q = q->next)
3036  { if (q->info.sto & Sattribute)
3037    { r = default_value(q, "default");
3038      t = ns_convert(q->sym->name);
3039      if (*t == '-' || is_anyAttribute(q->info.typ))
3040        fprintf(fd, "     <anyAttribute processContents=\"lax\"/><!-- member %s -->\n", q->sym->name);
3041      else if ((s = strchr(t, ':')))
3042      { if (r && *r)
3043          fprintf(fd, "     <attribute ref=\"%s\" use=\"default\"%s/>\n", t, r);
3044	else if (q->info.typ->type != Tpointer || q->info.minOccurs)
3045          fprintf(fd, "     <attribute ref=\"%s\" use=\"required\"/>\n", t);
3046	else
3047          fprintf(fd, "     <attribute ref=\"%s\" use=\"optional\"/>\n", t);
3048      }
3049      else
3050      { if (!s)
3051          s = t;
3052        else
3053	  s++;
3054	if (r && *r)
3055          fprintf(fd, "     <attribute name=\"%s\" type=\"%s\" use=\"default\"%s/>\n", s, wsdl_type(q->info.typ, ns1), r);
3056	else if (q->info.typ->type != Tpointer || q->info.minOccurs)
3057          fprintf(fd, "     <attribute name=\"%s\" type=\"%s\" use=\"required\"/>\n", s, wsdl_type(q->info.typ, ns1));
3058	else
3059          fprintf(fd, "     <attribute name=\"%s\" type=\"%s\" use=\"optional\"/>\n", s, wsdl_type(q->info.typ, ns1));
3060      }
3061      fflush(fd);
3062    }
3063  }
3064}
3065
3066void
3067gen_type_documentation(FILE *fd, Table *t, Entry *p, char *ns, char *ns1)
3068{ Service *sp;
3069  Data *d;
3070  fprintf(fd, "\n");
3071  if (!p->sym)
3072    return;
3073  for (sp = services; sp; sp = sp->next)
3074    if (!tagcmp(sp->ns, ns))
3075      for (d = sp->data; d; d = d->next)
3076        if (is_eq_nons(d->name, p->sym->name))
3077          fprintf(fd, "   <annotation>\n    <documentation>%s</documentation>\n   </annotation>\n", d->part);
3078}
3079
3080void
3081gen_nsmap(FILE *fd, Symbol *ns, char *URI)
3082{ Symbol *ns1;
3083  Service *sp;
3084  fprintf(fd, "{\n");
3085  for (ns1 = nslist; ns1; ns1 = ns1->next)
3086    /* if (ns1 != ns) */
3087    { for (sp = services; sp; sp = sp->next)
3088        if (!tagcmp(sp->ns, ns1->name) && sp->URI)
3089	  break;
3090        if (sp)
3091        { if (!strcmp(ns1->name, "SOAP-ENV"))
3092	    fprintf(fd, "\t{\"%s\", \"%s\", \"%s\", NULL},\n", ns_convert(ns1->name), sp->URI, envURI);
3093          else if (!strcmp(ns1->name, "SOAP-ENC"))
3094	    fprintf(fd, "\t{\"%s\", \"%s\", \"%s\", NULL},\n", ns_convert(ns1->name), sp->URI, encURI);
3095          else
3096	    fprintf(fd, "\t{\"%s\", \"%s\", NULL, NULL},\n", ns_convert(ns1->name), sp->URI);
3097        }
3098        else if (!strcmp(ns1->name, "SOAP-ENV"))
3099	  if (is_soap12(NULL))
3100	    fprintf(fd, "\t{\"SOAP-ENV\", \"%s\", \"http://schemas.xmlsoap.org/soap/envelope/\", NULL},\n", envURI);
3101	  else
3102	    fprintf(fd, "\t{\"SOAP-ENV\", \"%s\", \"http://www.w3.org/*/soap-envelope\", NULL},\n", envURI);
3103        else if (!strcmp(ns1->name, "SOAP-ENC"))
3104	  if (is_soap12(NULL))
3105	    fprintf(fd, "\t{\"SOAP-ENC\", \"%s\", \"http://schemas.xmlsoap.org/soap/encoding/\", NULL},\n", encURI);
3106	  else
3107	    fprintf(fd, "\t{\"SOAP-ENC\", \"%s\", \"http://www.w3.org/*/soap-encoding\", NULL},\n", encURI);
3108        else if (!strcmp(ns1->name, "xsi"))
3109	  fprintf(fd, "\t{\"xsi\", \"%s\", \"http://www.w3.org/*/XMLSchema-instance\", NULL},\n", xsiURI);
3110        else if (!strcmp(ns1->name, "xsd"))
3111	  fprintf(fd, "\t{\"xsd\", \"%s\", \"http://www.w3.org/*/XMLSchema\", NULL},\n", xsdURI);
3112        else
3113	  fprintf(fd, "\t{\"%s\", \"%s/%s.xsd\", NULL, NULL},\n", ns_convert(ns1->name), tmpURI, ns_convert(ns1->name));
3114    }
3115    /* fprintf(fd, "\t{\"%s\", \"%s\"},\n", ns_convert(ns->name), URI); */
3116    fprintf(fd, "\t{NULL, NULL, NULL, NULL}\n};\n");
3117}
3118
3119void
3120gen_proxy(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3121{ Entry *p, *q, *r;
3122  Table *t, *output;
3123  Service *sp;
3124  int flag;
3125  char *name1;
3126  name1 = ns_cname(name, NULL);
3127  for (sp = services; sp; sp = sp->next)
3128    if (!tagcmp(sp->ns, ns->name))
3129      break;
3130  fprintf(fd, "\n\n#ifndef %s%sProxy_H\n#define %s%sProxy_H\n#include \"%sH.h\"", prefix, name1, prefix, name1, prefix);
3131  if (nflag)
3132    fprintf(fd, "\nextern SOAP_NMAC struct Namespace %s_namespaces[];", prefix);
3133  if (namespaceid)
3134    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3135  fprintf(fd, "\nclass %s\n{   public:\n\t/// Runtime engine context allocated in constructor\n\tstruct soap *soap;\n\t/// Endpoint URL of service '%s' (change as needed)\n\tconst char *endpoint;\n\t/// Constructor allocates soap engine context, sets default endpoint URL, and sets namespace mapping table\n", name1, name);
3136  if (nflag)
3137    fprintf(fd, "\t%s() { soap = soap_new(); if (soap) soap->namespaces = %s_namespaces; endpoint = \"%s\"; };\n", name1, prefix, URL);
3138  else
3139  { fprintf(fd, "\t%s()\n\t{ soap = soap_new(); endpoint = \"%s\"; if (soap && !soap->namespaces) { static const struct Namespace namespaces[] = \n", name1, URL);
3140    gen_nsmap(fd, ns, URI);
3141    fprintf(fd, "\tsoap->namespaces = namespaces; } };\n");
3142  }
3143  fprintf(fd, "\t/// Destructor frees deserialized data and soap engine context\n\tvirtual ~%s() { if (soap) { soap_destroy(soap); soap_end(soap); soap_free(soap); } };\n", name1);
3144  fflush(fd);
3145  for (r = table->list; r; r = r->next)
3146    if (r->info.typ->type == Tfun && !(r->info.sto & Sextern) && has_ns_eq(ns->name, r->sym->name))
3147    { p = entry(table, r->sym);
3148      if (p)
3149        q = (Entry*)p->info.typ->ref;
3150      else
3151      { fprintf(stderr, "Internal error: no table entry\n");
3152        return;
3153      }
3154      p = entry(classtable, r->sym);
3155      if (!p)
3156      { fprintf(stderr, "Internal error: no parameter table entry\n");
3157        return;
3158      }
3159      output = (Table*)p->info.typ->ref;
3160      /*
3161      if ((s = strstr(r->sym->name, "__")))
3162        s += 2;
3163      else
3164        s = r->sym->name;
3165      fprintf(fd, "\tvirtual int %s(", s);
3166      */
3167      fprintf(fd, "\t/// Invoke '%s' of service '%s' and return error code (or SOAP_OK)\n", ns_remove(r->sym->name), name);
3168      fprintf(fd, "\tvirtual int %s(", ident(r->sym->name));
3169      flag = 0;
3170      for (t = output; t; t = t->prev)
3171      { p = t->list;
3172        if (p)
3173        { fprintf(fd, "%s%s", c_storage(p->info.sto), c_type_id(p->info.typ, p->sym->name));
3174          for (p = p->next; p; p = p->next)
3175            fprintf(fd, ", %s%s", c_storage(p->info.sto), c_type_id(p->info.typ, p->sym->name));
3176	  flag = 1;
3177        }
3178      }
3179      if (is_transient(q->info.typ))
3180        fprintf(fd,") { return soap ? soap_send_%s(soap, endpoint, NULL", ident(r->sym->name));
3181      else if (flag)
3182        fprintf(fd,", %s%s) { return soap ? soap_call_%s(soap, endpoint, NULL", c_storage(q->info.sto), c_type_id(q->info.typ, q->sym->name), ident(r->sym->name));
3183      else
3184        fprintf(fd,"%s%s) { return soap ? soap_call_%s(soap, endpoint, NULL", c_storage(q->info.sto), c_type_id(q->info.typ, q->sym->name), ident(r->sym->name));
3185      /* the action is now handled by the soap_call/soap_send operation when we pass NULL
3186      m = NULL;
3187      if (sp && (s = strstr(r->sym->name, "__")))
3188        for (m = sp->list; m; m = m->next)
3189          if (m->part && m->mess == ACTION && !strcmp(m->name, s+2))
3190          { if (*m->part == '"')
3191	      fprintf(fd, "%s", m->part);
3192            else
3193	      fprintf(fd, "\"%s\"", m->part);
3194	    break;
3195	  }
3196      if (!m)
3197        fprintf(fd, "NULL");
3198      */
3199      for (t = output; t; t = t->prev)
3200        for (p = t->list; p; p = p->next)
3201          fprintf(fd, ", %s", ident(p->sym->name));
3202      if (is_transient(q->info.typ))
3203        fprintf(fd,") : SOAP_EOM; };\n");
3204      else
3205        fprintf(fd,", %s) : SOAP_EOM; };\n", ident(q->sym->name));
3206      fflush(fd);
3207    }
3208  fprintf(fd, "};");
3209  if (namespaceid)
3210    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
3211  fprintf(fd, "\n#endif\n");
3212}
3213
3214void
3215gen_object(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3216{ char *name1;
3217  Entry *method;
3218  name1 = ns_cname(name, NULL);
3219  fprintf(fd, "\n\n#ifndef %s%sObject_H\n#define %s%sObject_H\n#include \"%sH.h\"", prefix, name1, prefix, name1, prefix);
3220  banner(fd, "Service Object");
3221  if (nflag)
3222    fprintf(fd, "\nextern SOAP_NMAC struct Namespace %s_namespaces[];", prefix);
3223  if (namespaceid)
3224    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3225  fprintf(fd, "\nclass %sService : public soap\n{    public:", name1);
3226  if (nflag)
3227    fprintf(fd, "\n\t%sService()\n\t{ this->namespaces = %s_namespaces; };", name1, prefix);
3228  else
3229  { fprintf(fd, "\n\t%sService()\n\t{ static const struct Namespace namespaces[] =\n", name1);
3230    gen_nsmap(fd, ns, URI);
3231    fprintf(fd, "\tif (!this->namespaces) this->namespaces = namespaces; };");
3232  }
3233  fprintf(fd, "\n\tvirtual ~%sService() { };", name1);
3234  fprintf(fd, "\n\t/// Bind service to port (returns master socket or SOAP_INVALID_SOCKET)");
3235  fprintf(fd, "\n\tvirtual\tSOAP_SOCKET bind(const char *host, int port, int backlog) { return soap_bind(this, host, port, backlog); };");
3236  fprintf(fd, "\n\t/// Accept next request (returns socket or SOAP_INVALID_SOCKET)");
3237  fprintf(fd, "\n\tvirtual\tSOAP_SOCKET accept() { return soap_accept(this); };");
3238  fprintf(fd, "\n\t/// Serve this request (returns error code or SOAP_OK)");
3239  if (nflag)
3240    fprintf(fd, "\n\tvirtual\tint serve() { return %s_serve(this); };", prefix);
3241  else
3242    fprintf(fd, "\n\tvirtual\tint serve() { return soap_serve(this); };");
3243  fprintf(fd, "\n};");
3244  banner(fd, "Service Operations (you should define these globally)");
3245  for (method = table->list; method; method = method->next)
3246  { if (method->info.typ->type == Tfun && !(method->info.sto & Sextern))
3247    { Entry *p, *q=entry(table, method->sym);
3248      Table *output;
3249      if (q)
3250        p = (Entry*)q->info.typ->ref;
3251      else
3252      { fprintf(stderr, "Internal error: no table entry\n");
3253        return;
3254      }
3255      q = entry(classtable, method->sym);
3256      output = (Table*)q->info.typ->ref;
3257      fprintf(fd, "\n\nSOAP_FMAC5 int SOAP_FMAC6 %s(struct soap*", ident(method->sym->name));
3258      gen_params(fd, output, p, 1);
3259      fprintf(fd, ";");
3260    }
3261  }
3262  if (namespaceid)
3263    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
3264  fprintf(fd, "\n\n#endif\n");
3265}
3266
3267void
3268gen_proxy_header(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3269{ Entry *p, *method;
3270  Table *t;
3271  fprintf(fd, "\n\n#ifndef %s%s_H\n#define %s%s_H\n#include \"%sH.h\"", prefix, name, prefix, name, prefix);
3272  if (namespaceid)
3273    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3274  fprintf(fd, "\n\nclass SOAP_CMAC %s : public soap\n{ public:", name);
3275  fprintf(fd, "\n\t/// Endpoint URL of service '%s' (change as needed)", name);
3276  fprintf(fd, "\n\tconst char *soap_endpoint;");
3277  fprintf(fd, "\n\t/// Constructor");
3278  fprintf(fd, "\n\t%s();", name);
3279  fprintf(fd, "\n\t/// Constructor with copy of another engine state");
3280  fprintf(fd, "\n\t%s(const struct soap&);", name);
3281  fprintf(fd, "\n\t/// Constructor with engine input+output mode control");
3282  fprintf(fd, "\n\t%s(soap_mode iomode);", name);
3283  fprintf(fd, "\n\t/// Constructor with engine input and output mode control");
3284  fprintf(fd, "\n\t%s(soap_mode imode, soap_mode omode);", name);
3285  fprintf(fd, "\n\t/// Destructor frees deserialized data");
3286  fprintf(fd, "\n\tvirtual\t~%s();", name);
3287  fprintf(fd, "\n\t/// Initializer used by constructor");
3288  fprintf(fd, "\n\tvirtual\tvoid %s_init(soap_mode imode, soap_mode omode);", name);
3289  fprintf(fd, "\n\t/// Disables and removes SOAP Header from message");
3290  fprintf(fd, "\n\tvirtual\tvoid soap_noheader();");
3291  p = entry(classtable, lookup("SOAP_ENV__Header"));
3292  if (p)
3293  { t = p->info.typ->ref;
3294    if (t && t->list && !is_void(t->list->info.typ))
3295    { fprintf(fd, "\n\t/// Put SOAP Header in message");
3296      fprintf(fd, "\n\tvirtual\tvoid soap_header(");
3297      gen_params(fd, t, NULL, 0);
3298      fprintf(fd, ";");
3299      fprintf(fd, "\n\t/// Get SOAP Header structure (NULL when absent)");
3300      fprintf(fd, "\n\tvirtual\tconst SOAP_ENV__Header *soap_header();");
3301    }
3302  }
3303  fprintf(fd, "\n\t/// Get SOAP Fault structure (NULL when absent)");
3304  fprintf(fd, "\n\tvirtual\tconst SOAP_ENV__Fault *soap_fault();");
3305  fprintf(fd, "\n\t/// Get SOAP Fault string (NULL when absent)");
3306  fprintf(fd, "\n\tvirtual\tconst char *soap_fault_string();");
3307  fprintf(fd, "\n\t/// Get SOAP Fault detail as string (NULL when absent)");
3308  fprintf(fd, "\n\tvirtual\tconst char *soap_fault_detail();");
3309  fprintf(fd, "\n\t/// Force close connection (normally automatic, except for send_X ops)");
3310  fprintf(fd, "\n\tvirtual\tint soap_close_socket();");
3311  fprintf(fd, "\n\t/// Print fault");
3312  fprintf(fd, "\n\tvirtual\tvoid soap_print_fault(FILE*);");
3313  fprintf(fd, "\n#ifndef WITH_LEAN\n\t/// Print fault to stream");
3314  fprintf(fd, "\n\tvirtual\tvoid soap_stream_fault(std::ostream&);");
3315  fprintf(fd, "\n\t/// Put fault into buffer");
3316  fprintf(fd, "\n\tvirtual\tchar *soap_sprint_fault(char *buf, size_t len);\n#endif");
3317  for (method = table->list; method; method = method->next)
3318    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && has_ns_eq(ns->name, method->sym->name))
3319      gen_method(fd, table, method, 0);
3320  fprintf(fd, "\n};");
3321  if (namespaceid)
3322    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
3323  fprintf(fd, "\n#endif\n");
3324}
3325
3326void
3327gen_proxy_code(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3328{ Entry *p, *method, *param;
3329  Table *t;
3330  fprintf(fd, "\n\n#include \"%s%s.h\"", prefix, name);
3331  if (namespaceid)
3332    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3333  fprintf(fd, "\n\n%s::%s()\n{\t%s_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);\n}", name, name, name);
3334  fprintf(fd, "\n\n%s::%s(const struct soap &soap)\n{\tsoap_copy_context(this, &soap);\n\t%s_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);\n}", name, name, name);
3335  fprintf(fd, "\n\n%s::%s(soap_mode iomode)\n{\t%s_init(iomode, iomode);\n}", name, name, name);
3336  fprintf(fd, "\n\n%s::%s(soap_mode imode, soap_mode omode)\n{\t%s_init(imode, omode);\n}", name, name, name);
3337  fprintf(fd, "\n\nvoid %s::%s_init(soap_mode imode, soap_mode omode)\n{\tsoap_imode(this, imode);\n\tsoap_omode(this, omode);\n\tsoap_endpoint = NULL;\n\tstatic const struct Namespace namespaces[] =\n", name, name);
3338  gen_nsmap(fd, ns, URI);
3339  if (nflag)
3340    fprintf(fd, "\tthis->namespaces = namespaces;\n}");
3341  else
3342    fprintf(fd, "\tif (!this->namespaces)\n\t\tthis->namespaces = namespaces;\n}");
3343  fprintf(fd, "\n\n%s::~%s()\n{ }", name, name);
3344  fprintf(fd, "\n\nvoid %s::soap_noheader()\n{\theader = NULL;\n}", name);
3345  p = entry(classtable, lookup("SOAP_ENV__Header"));
3346  if (p)
3347  { t = p->info.typ->ref;
3348    if (t && t->list && !is_void(t->list->info.typ))
3349    { fprintf(fd, "\n\nvoid %s::soap_header(", name);
3350      gen_params(fd, t, NULL, 0);
3351      fprintf(fd, "\n{\t::soap_header(this);");
3352      for (param = t->list; param; param = param->next)
3353      { if (namespaceid)
3354          fprintf(fd, "\n\t((%s::SOAP_ENV__Header*)this->header)->%s = %s;", namespaceid, ident(param->sym->name), ident(param->sym->name));
3355        else
3356          fprintf(fd, "\n\tthis->header->%s = %s;", ident(param->sym->name), ident(param->sym->name));
3357      }
3358      fprintf(fd, "\n}");
3359      if (namespaceid)
3360        fprintf(fd, "\n\nconst SOAP_ENV__Header *%s::soap_header()\n{\treturn (const %s::SOAP_ENV__Header*)this->header;\n}", name, namespaceid);
3361      else
3362        fprintf(fd, "\n\nconst SOAP_ENV__Header *%s::soap_header()\n{\treturn this->header;\n}", name);
3363    }
3364  }
3365  if (namespaceid)
3366    fprintf(fd, "\n\nconst SOAP_ENV__Fault *%s::soap_fault()\n{\treturn (const %s::SOAP_ENV__Fault*)this->fault;\n}", name, namespaceid);
3367  else
3368    fprintf(fd, "\n\nconst SOAP_ENV__Fault *%s::soap_fault()\n{\treturn this->fault;\n}", name);
3369  fprintf(fd, "\n\nconst char *%s::soap_fault_string()\n{\treturn *soap_faultstring(this);\n}", name);
3370  fprintf(fd, "\n\nconst char *%s::soap_fault_detail()\n{\treturn *soap_faultdetail(this);\n}", name);
3371  fprintf(fd, "\n\nint %s::soap_close_socket()\n{\treturn soap_closesock(this);\n}", name);
3372  fprintf(fd, "\n\nvoid %s::soap_print_fault(FILE *fd)\n{\t::soap_print_fault(this, fd);\n}", name);
3373  fprintf(fd, "\n\n#ifndef WITH_LEAN\nvoid %s::soap_stream_fault(std::ostream& os)\n{\t::soap_stream_fault(this, os);\n}", name);
3374  fprintf(fd, "\n\nchar *%s::soap_sprint_fault(char *buf, size_t len)\n{\treturn ::soap_sprint_fault(this, buf, len);\n}\n#endif", name);
3375  for (method = table->list; method; method = method->next)
3376    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && !is_imported(method->info.typ) && has_ns_eq(ns->name, method->sym->name))
3377      gen_call_method(fd, table, method, name);
3378  if (namespaceid)
3379    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
3380  fprintf(fd,"\n/* End of client proxy code */\n");
3381}
3382
3383void
3384gen_object_header(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3385{ Entry *p, *method;
3386  Table *t;
3387  fprintf(fd, "\n\n#ifndef %s%s_H\n#define %s%s_H\n#include \"%sH.h\"", prefix, name, prefix, name, prefix);
3388  if (namespaceid)
3389    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3390  fprintf(fd, "\nclass SOAP_CMAC %s : public soap\n{ public:", name);
3391  fprintf(fd, "\n\t/// Constructor");
3392  fprintf(fd, "\n\t%s();", name);
3393  fprintf(fd, "\n\t/// Constructor with copy of another engine state");
3394  fprintf(fd, "\n\t%s(const struct soap&);", name);
3395  fprintf(fd, "\n\t/// Constructor with engine input+output mode control");
3396  fprintf(fd, "\n\t%s(soap_mode iomode);", name);
3397  fprintf(fd, "\n\t/// Constructor with engine input and output mode control");
3398  fprintf(fd, "\n\t%s(soap_mode imode, soap_mode omode);", name);
3399  fprintf(fd, "\n\t/// Destructor frees all data");
3400  fprintf(fd, "\n\tvirtual ~%s();", name);
3401  fprintf(fd, "\n\t/// Initializer used by constructor");
3402  fprintf(fd, "\n\tvirtual\tvoid %s_init(soap_mode imode, soap_mode omode);", name);
3403  fprintf(fd, "\n\t/// Create a copy");
3404  fprintf(fd, "\n\tvirtual\t%s *copy();", name);
3405  fprintf(fd, "\n\t/// Force close connection (normally automatic)");
3406  fprintf(fd, "\n\tvirtual\tint soap_close_socket();");
3407  fprintf(fd, "\n\t/// Return sender-related fault to sender");
3408  fprintf(fd, "\n\tvirtual\tint soap_senderfault(const char *string, const char *detailXML);");
3409  fprintf(fd, "\n\t/// Return sender-related fault with SOAP 1.2 subcode to sender");
3410  fprintf(fd, "\n\tvirtual\tint soap_senderfault(const char *subcodeQName, const char *string, const char *detailXML);");
3411  fprintf(fd, "\n\t/// Return receiver-related fault to sender");
3412  fprintf(fd, "\n\tvirtual\tint soap_receiverfault(const char *string, const char *detailXML);");
3413  fprintf(fd, "\n\t/// Return receiver-related fault with SOAP 1.2 subcode to sender");
3414  fprintf(fd, "\n\tvirtual\tint soap_receiverfault(const char *subcodeQName, const char *string, const char *detailXML);");
3415  fprintf(fd, "\n\t/// Print fault");
3416  fprintf(fd, "\n\tvirtual\tvoid soap_print_fault(FILE*);");
3417  fprintf(fd, "\n#ifndef WITH_LEAN\n\t/// Print fault to stream");
3418  fprintf(fd, "\n\tvirtual\tvoid soap_stream_fault(std::ostream&);");
3419  fprintf(fd, "\n\t/// Put fault into buffer");
3420  fprintf(fd, "\n\tvirtual\tchar *soap_sprint_fault(char *buf, size_t len);\n#endif");
3421  fprintf(fd, "\n\t/// Disables and removes SOAP Header from message");
3422  fprintf(fd, "\n\tvirtual\tvoid soap_noheader();");
3423  p = entry(classtable, lookup("SOAP_ENV__Header"));
3424  if (p)
3425  { t = p->info.typ->ref;
3426    if (t && t->list && !is_void(t->list->info.typ))
3427    { fprintf(fd, "\n\t/// Put SOAP Header in message");
3428      fprintf(fd, "\n\tvirtual\tvoid soap_header(");
3429      gen_params(fd, t, NULL, 0);
3430      fprintf(fd, ";");
3431      fprintf(fd, "\n\t/// Get SOAP Header structure (NULL when absent)");
3432      fprintf(fd, "\n\tvirtual\tconst SOAP_ENV__Header *soap_header();");
3433    }
3434  }
3435  fprintf(fd, "\n\t/// Run simple single-thread iterative service on port until a connection error occurs (returns error code or SOAP_OK), use this->bind_flag = SO_REUSEADDR to rebind for a rerun");
3436  fprintf(fd, "\n\tvirtual\tint run(int port);");
3437  fprintf(fd, "\n\t/// Bind service to port (returns master socket or SOAP_INVALID_SOCKET)");
3438  fprintf(fd, "\n\tvirtual\tSOAP_SOCKET bind(const char *host, int port, int backlog);");
3439  fprintf(fd, "\n\t/// Accept next request (returns socket or SOAP_INVALID_SOCKET)");
3440  fprintf(fd, "\n\tvirtual\tSOAP_SOCKET accept();");
3441  fprintf(fd, "\n\t/// Serve this request (returns error code or SOAP_OK)");
3442  fprintf(fd, "\n\tvirtual\tint serve();");
3443  fprintf(fd, "\n\t/// Used by serve() to dispatch a request (returns error code or SOAP_OK)");
3444  fprintf(fd, "\n\tvirtual\tint dispatch();");
3445  fprintf(fd, "\n\n\t///\n\t/// Service operations (you should define these):\n\t///");
3446  for (method = table->list; method; method = method->next)
3447    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && has_ns_eq(ns->name, method->sym->name))
3448      gen_method(fd, table, method, 1);
3449  fprintf(fd, "\n};");
3450  if (namespaceid)
3451    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
3452  fprintf(fd, "\n#endif\n");
3453}
3454
3455void
3456gen_method(FILE *fd, Table *table, Entry *method, int server)
3457{ Table *params;
3458  Entry *result, *p;
3459  result = method->info.typ->ref;
3460  p = entry(classtable, method->sym);
3461  if (!p)
3462    execerror("no table entry");
3463  params = (Table*)p->info.typ->ref;
3464  if (server || !is_transient(result->info.typ))
3465  { if (is_transient(result->info.typ))
3466      fprintf(fd, "\n\n\t/// Web service one-way operation '%s' (return error code, SOAP_OK (no response), or send_%s_empty_response())", ns_remove(method->sym->name), ns_remove(method->sym->name));
3467    else
3468      fprintf(fd, "\n\n\t/// Web service operation '%s' (returns error code or SOAP_OK)", ns_remove(method->sym->name));
3469    fprintf(fd, "\n\tvirtual\tint %s(", ns_cname(method->sym->name, NULL));
3470    gen_params(fd, params, result, 0);
3471    fprintf(fd, ";");
3472    if (is_transient(result->info.typ))
3473      fprintf(fd, "\n\tvirtual\tint send_%s_empty_response(int httpcode) { return soap_send_empty_response(this, httpcode); }", ns_cname(method->sym->name, NULL));
3474  }
3475  else
3476  { fprintf(fd, "\n\n\t/// Web service one-way send operation 'send_%s' (returns error code or SOAP_OK)", ns_remove(method->sym->name));
3477    fprintf(fd, "\n\tvirtual\tint send_%s(", ns_cname(method->sym->name, NULL));
3478    gen_params(fd, params, result, 0);
3479    fprintf(fd, ";\n\t/// Web service one-way receive operation 'recv_%s' (returns error code or SOAP_OK)", ns_remove(method->sym->name));
3480    fprintf(fd, ";\n\tvirtual\tint recv_%s(", ns_cname(method->sym->name, NULL));
3481    fprintf(fd, "struct %s&);", ident(method->sym->name));
3482    fprintf(fd, "\n\t/// Web service receive of HTTP Accept acknowledgment for one-way send operation 'send_%s' (returns error code or SOAP_OK)", ns_remove(method->sym->name));
3483    fprintf(fd, "\n\tvirtual\tint recv_%s_empty_response() { return soap_recv_empty_response(this); }", ns_cname(method->sym->name, NULL));
3484    fprintf(fd, "\n\t/// Web service one-way synchronous send operation '%s' with HTTP Accept/OK response receive (returns error code or SOAP_OK)", ns_remove(method->sym->name));
3485    fprintf(fd, "\n\tvirtual\tint %s(", ns_cname(method->sym->name, NULL));
3486    gen_params(fd, params, result, 0);
3487    fprintf(fd, " { if (send_%s(", ns_cname(method->sym->name, NULL));
3488    gen_args(fd, params, result, 0);
3489    fprintf(fd, " || soap_recv_empty_response(this)) return this->error; return SOAP_OK; }");
3490  }
3491}
3492
3493void
3494gen_params(FILE *fd, Table *params, Entry *result, int flag)
3495{ Entry *param;
3496  for (param = params->list; param; param = param->next)
3497    fprintf(fd, "%s%s%s", flag || param != params->list ? ", " : "", c_storage(param->info.sto), c_type_id(param->info.typ, param->sym->name));
3498  if (!result || is_transient(result->info.typ))
3499    fprintf(fd, ")");
3500  else
3501    fprintf(fd, "%s%s%s)", flag || params->list ? ", " : "", c_storage(result->info.sto), c_type_id(result->info.typ, result->sym->name));
3502}
3503
3504void
3505gen_args(FILE *fd, Table *params, Entry *result, int flag)
3506{ Entry *param;
3507  for (param = params->list; param; param = param->next)
3508    fprintf(fd, "%s%s", flag || param != params->list ? ", " : "", param->sym->name);
3509  if (!result || is_transient(result->info.typ))
3510    fprintf(fd, ")");
3511  else
3512    fprintf(fd, "%s%s)", flag || params->list ? ", " : "", result->sym->name);
3513}
3514
3515void
3516gen_call_method(FILE *fd, Table *table, Entry *method, char *name)
3517{ Service *sp;
3518  Method *m;
3519  char *style, *encoding;
3520  char *xtag, *xtyp;
3521  char *action = NULL, *method_style = NULL, *method_encoding = NULL, *method_response_encoding = NULL;
3522  Table *params;
3523  Entry *param, *result, *p, *response = NULL;
3524  result = method->info.typ->ref;
3525  p = entry(classtable, method->sym);
3526  if (!p)
3527    execerror("no table entry");
3528  params = (Table*)p->info.typ->ref;
3529  if (!is_response(result->info.typ) && !is_XML(result->info.typ))
3530    response = get_response(method->info.typ);
3531  if (name)
3532  { if (!is_transient(result->info.typ))
3533      fprintf(fd, "\n\nint %s::%s(", name, ns_cname(method->sym->name, NULL));
3534    else
3535      fprintf(fd, "\n\nint %s::send_%s(", name, ns_cname(method->sym->name, NULL));
3536    gen_params(fd, params, result, 0);
3537  }
3538  else if (!is_transient(result->info.typ))
3539  { fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_call_%s(struct soap *soap, const char *soap_endpoint, const char *soap_action", ident(method->sym->name));
3540    gen_params(fheader, params, result, 1);
3541    fprintf(fd, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_call_%s(struct soap *soap, const char *soap_endpoint, const char *soap_action", ident(method->sym->name));
3542    gen_params(fd, params, result, 1);
3543  }
3544  else
3545  { fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_send_%s(struct soap *soap, const char *soap_endpoint, const char *soap_action", ident(method->sym->name));
3546    gen_params(fheader, params, result, 1);
3547    fprintf(fd, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_send_%s(struct soap *soap, const char *soap_endpoint, const char *soap_action", ident(method->sym->name));
3548    gen_params(fd, params, result, 1);
3549  }
3550  if (name)
3551    fprintf(fd, "\n{\tstruct soap *soap = this;\n");
3552  else
3553  { fprintf(fheader, ";");
3554    fprintf(fd, "\n{");
3555  }
3556  fprintf(fd, "\tstruct %s soap_tmp_%s;", ident(method->sym->name), ident(method->sym->name));
3557  if (!is_response(result->info.typ) && response)
3558    fprintf(fd, "\n\tstruct %s *soap_tmp_%s;", c_ident(response->info.typ), c_ident(response->info.typ));
3559  for (sp = services; sp; sp = sp->next)
3560  { if (has_ns_eq(sp->ns, method->sym->name))
3561    { style = sp->style;
3562      encoding = sp->encoding;
3563      method_style = style;
3564      method_encoding = encoding;
3565      method_response_encoding = NULL;
3566      for (m = sp->list; m; m = m->next)
3567      { if (is_eq_nons(m->name, method->sym->name))
3568        { if (m->mess == ACTION)
3569            action = m->part;
3570          else if (m->mess == ENCODING)
3571            method_encoding = m->part;
3572          else if (m->mess == RESPONSE_ENCODING)
3573            method_response_encoding = m->part;
3574          else if (m->mess == STYLE)
3575            method_style = m->part;
3576        }
3577      }
3578      break;
3579    }
3580  }
3581  if (name)
3582    fprintf(fd, "\n\tconst char *soap_action = NULL;");
3583  if (sp && sp->URL)
3584    fprintf(fd, "\n\tif (!soap_endpoint)\n\t\tsoap_endpoint = \"%s\";", sp->URL);
3585  if (action)
3586  { if (name)
3587      fprintf(fd, "\n\tsoap_action = ");
3588    else
3589      fprintf(fd, "\n\tif (!soap_action)\n\t\tsoap_action = ");
3590    if (*action == '"')
3591      fprintf(fd, "%s;", action);
3592    else
3593      fprintf(fd, "\"%s\";", action);
3594  }
3595  if (!method_response_encoding)
3596    method_response_encoding = method_encoding;
3597  if (sp && sp->URI && method_encoding)
3598  { if (is_literal(method_encoding))
3599      fprintf(fd, "\n\tsoap->encodingStyle = NULL;");
3600    else if (method_encoding)
3601      fprintf(fd, "\n\tsoap->encodingStyle = \"%s\";", method_encoding);
3602  }
3603  else if (!eflag)
3604    fprintf(fd, "\n\tsoap->encodingStyle = NULL;");
3605  for (param = params->list; param; param = param->next)
3606  { if (param->info.typ->type == Tarray)
3607      fprintf(fd, "\n\tmemcpy(soap_tmp_%s.%s, %s, sizeof(%s));", ident(method->sym->name), ident(param->sym->name), ident(param->sym->name), c_type(param->info.typ));
3608    else
3609      fprintf(fd, "\n\tsoap_tmp_%s.%s = %s;", ident(method->sym->name), ident(param->sym->name), ident(param->sym->name));
3610  }
3611  fprintf(fd, "\n\tsoap_begin(soap);");
3612  fprintf(fd, "\n\tsoap_serializeheader(soap);");
3613  fprintf(fd, "\n\tsoap_serialize_%s(soap, &soap_tmp_%s);", ident(method->sym->name), ident(method->sym->name));
3614  fprintf(fd, "\n\tif (soap_begin_count(soap))\n\t\treturn soap->error;");
3615  fprintf(fd, "\n\tif (soap->mode & SOAP_IO_LENGTH)");
3616  fprintf(fd, "\n\t{\tif (soap_envelope_begin_out(soap)");
3617  fprintf(fd, "\n\t\t || soap_putheader(soap)");
3618  fprintf(fd, "\n\t\t || soap_body_begin_out(soap)");
3619  fprintf(fd, "\n\t\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", ident(method->sym->name), ident(method->sym->name), ns_convert(method->sym->name));
3620  fprintf(fd, "\n\t\t || soap_body_end_out(soap)");
3621  fprintf(fd, "\n\t\t || soap_envelope_end_out(soap))");
3622  fprintf(fd, "\n\t\t\t return soap->error;");
3623  fprintf(fd, "\n\t}");
3624  fprintf(fd, "\n\tif (soap_end_count(soap))\n\t\treturn soap->error;");
3625  fprintf(fd, "\n\tif (soap_connect(soap, soap_endpoint, soap_action)");
3626  fprintf(fd, "\n\t || soap_envelope_begin_out(soap)");
3627  fprintf(fd, "\n\t || soap_putheader(soap)");
3628  fprintf(fd, "\n\t || soap_body_begin_out(soap)");
3629  fprintf(fd, "\n\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", ident(method->sym->name), ident(method->sym->name), ns_convert(method->sym->name));
3630  fprintf(fd, "\n\t || soap_body_end_out(soap)");
3631  fprintf(fd, "\n\t || soap_envelope_end_out(soap)");
3632  fprintf(fd, "\n\t || soap_end_send(soap))");
3633  fprintf(fd, "\n\t\treturn soap_closesock(soap);");
3634  if (is_transient(result->info.typ))
3635  { fprintf(fd, "\n\treturn SOAP_OK;\n}");
3636    if (name)
3637    { fprintf(fd, "\n\nint %s::recv_%s(", name, ns_cname(method->sym->name, NULL));
3638      fprintf(fd, "struct %s& tmp)\n{\n\tstruct soap *soap = this;\n\tstruct %s *%s = &tmp;", ident(method->sym->name), ident(method->sym->name), ident(result->sym->name));
3639    }
3640    else
3641    { fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_recv_%s(struct soap *soap, ", ident(method->sym->name));
3642      fprintf(fd, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_recv_%s(struct soap *soap, ", ident(method->sym->name));
3643      fprintf(fheader, "struct %s *%s);\n", ident(method->sym->name), ident(result->sym->name));
3644      fprintf(fd, "struct %s *%s)\n{", ident(method->sym->name), ident(result->sym->name));
3645    }
3646    fprintf(fd, "\n\tsoap_default_%s(soap, %s);", ident(method->sym->name), ident(result->sym->name));
3647    fprintf(fd, "\n\tsoap_begin(soap);");
3648  }
3649  else if (result->info.typ->type == Tarray)
3650    fprintf(fd, "\n\tsoap_default_%s(soap, %s);", c_ident(result->info.typ), ident(result->sym->name));
3651  else if (result->info.typ->type == Treference && ((Tnode*)result->info.typ->ref)->type == Tclass && !is_external(result->info.typ->ref) && !is_volatile(result->info.typ->ref))
3652    fprintf(fd, "\n\tif (!&%s)\n\t\treturn soap_closesock(soap);\n\t%s.soap_default(soap);", ident(result->sym->name), ident(result->sym->name));
3653  else if (((Tnode*)result->info.typ->ref)->type == Tclass && !is_external(result->info.typ->ref) && !is_volatile(result->info.typ->ref))
3654    fprintf(fd, "\n\tif (!%s)\n\t\treturn soap_closesock(soap);\n\t%s->soap_default(soap);", ident(result->sym->name), ident(result->sym->name));
3655  else if (result->info.typ->type == Treference && ((Tnode*)result->info.typ->ref)->type == Tpointer)
3656    fprintf(fd, "\n\t%s = NULL;", ident(result->sym->name));
3657  else if (((Tnode*)result->info.typ->ref)->type == Tpointer)
3658    fprintf(fd, "\n\tif (!%s)\n\t\treturn soap_closesock(soap);\n\t*%s = NULL;", ident(result->sym->name), ident(result->sym->name));
3659  else if (result->info.typ->type == Treference)
3660    fprintf(fd, "\n\tif (!&%s)\n\t\treturn soap_closesock(soap);\n\tsoap_default_%s(soap, &%s);", ident(result->sym->name), c_ident((Tnode*)result->info.typ->ref), ident(result->sym->name));
3661  else if (!is_void(result->info.typ))
3662    fprintf(fd, "\n\tif (!%s)\n\t\treturn soap_closesock(soap);\n\tsoap_default_%s(soap, %s);", ident(result->sym->name), c_ident((Tnode*)result->info.typ->ref), ident(result->sym->name));
3663  fprintf(fd,"\n\tif (soap_begin_recv(soap)");
3664  fprintf(fd,"\n\t || soap_envelope_begin_in(soap)");
3665  fprintf(fd,"\n\t || soap_recv_header(soap)");
3666  fprintf(fd,"\n\t || soap_body_begin_in(soap))");
3667  fprintf(fd,"\n\t\treturn soap_closesock(soap);");
3668  if (is_transient(result->info.typ))
3669  { fprintf(fd,"\n\tsoap_get_%s(soap, %s, \"%s\", NULL);", ident(method->sym->name), ident(result->sym->name), ns_convert(method->sym->name));
3670    fprintf(fd,"\n\tif (soap->error == SOAP_TAG_MISMATCH && soap->level == 2)\n\t\tsoap->error = SOAP_NO_METHOD;");
3671    fprintf(fd,"\n\tif (soap->error");
3672    fprintf(fd,"\n\t || soap_body_end_in(soap)");
3673    fprintf(fd,"\n\t || soap_envelope_end_in(soap)");
3674    fprintf(fd,"\n\t || soap_end_recv(soap))");
3675    fprintf(fd,"\n\t\treturn soap_closesock(soap);");
3676    fprintf(fd,"\n\treturn soap_closesock(soap);\n}");
3677    fflush(fd);
3678    return;
3679  }
3680
3681  if (has_ns_eq(NULL, result->sym->name))
3682  { xtyp = xsi_type(result->info.typ);
3683    xtag = ns_convert(result->sym->name);
3684  }
3685  else
3686  { xtyp = "";
3687    xtag = xml_tag(result->info.typ);
3688  }
3689  if (!is_response(result->info.typ) && response)
3690  { fprintf(fd,"\n\tsoap_tmp_%s = soap_get_%s(soap, NULL, \"%s\", \"\");", c_ident(response->info.typ), c_ident(response->info.typ), xml_tag(response->info.typ));
3691  }
3692  else if (result->info.typ->type == Treference && ((Tnode *) result->info.typ->ref)->type == Tclass && !is_external(result->info.typ->ref) && !is_volatile(result->info.typ->ref) && !is_dynamic_array(result->info.typ->ref))
3693    fprintf(fd,"\n\t%s.soap_get(soap, \"%s\", \"%s\");", ident(result->sym->name), xtag, xtyp);
3694  else if (result->info.typ->type == Tpointer && ((Tnode *) result->info.typ->ref)->type == Tclass && !is_external(result->info.typ->ref) && !is_volatile(result->info.typ->ref) && !is_dynamic_array(result->info.typ->ref))
3695    fprintf(fd,"\n\t%s->soap_get(soap, \"%s\", \"%s\");", ident(result->sym->name), xtag, xtyp);
3696  else if (result->info.typ->type == Treference && ((Tnode *) result->info.typ->ref)->type == Tstruct && !is_external(result->info.typ->ref) && !is_volatile(result->info.typ->ref) && !is_dynamic_array(result->info.typ->ref))
3697  { fprintf(fd,"\n\tsoap_get_%s(soap, &%s, \"%s\", \"%s\");", c_ident(result->info.typ->ref), ident(result->sym->name), xtag, xtyp);
3698  }
3699  else if (result->info.typ->type == Tpointer && ((Tnode *) result->info.typ->ref)->type == Tstruct && !is_dynamic_array(result->info.typ->ref))
3700  {
3701    fprintf(fd,"\n\tsoap_get_%s(soap, %s, \"%s\", \"%s\");", c_ident(result->info.typ->ref), ident(result->sym->name), xtag, xtyp);
3702  }
3703  else if (result->info.typ->type == Tpointer && is_XML(result->info.typ->ref) && is_string(result->info.typ->ref))
3704  { fprintf(fd,"\n\tsoap_inliteral(soap, NULL, %s);", ident(result->sym->name));
3705  }
3706  else if (result->info.typ->type == Treference && is_XML(result->info.typ->ref) && is_string(result->info.typ->ref))
3707  { fprintf(fd,"\n\tsoap_inliteral(soap, NULL, &%s);", ident(result->sym->name));
3708  }
3709  else if (result->info.typ->type == Tpointer && is_XML(result->info.typ->ref) && is_wstring(result->info.typ->ref))
3710  { fprintf(fd,"\n\tsoap_inwliteral(soap, NULL, %s);", ident(result->sym->name));
3711  }
3712  else if (result->info.typ->type == Treference && is_XML(result->info.typ->ref) && is_wstring(result->info.typ->ref))
3713  { fprintf(fd,"\n\tsoap_inwliteral(soap, NULL, &%s);", ident(result->sym->name));
3714  }
3715  /* Note: the trouble with "" tags is that SOAP-ENV:Fault cannot be parsed. However, SOAP encoding does not care about the result struct name!
3716  else if (response && !is_literal(method_response_encoding))
3717  { fprintf(fd,"\n\tsoap_tmp_%s = soap_get_%s(soap, NULL, \"\", \"\");", c_ident(response->info.typ), c_ident(response->info.typ));
3718  }
3719  */
3720  else if (result->info.typ->type == Treference)
3721  { fprintf(fd,"\n\tsoap_get_%s(soap, &%s, \"%s\", \"%s\");", c_ident(result->info.typ), ident(result->sym->name), xtag, xtyp);
3722  }
3723  else
3724  { fprintf(fd,"\n\tsoap_get_%s(soap, %s, \"%s\", \"%s\");", c_ident(result->info.typ), ident(result->sym->name), xtag, xtyp);
3725  }
3726  fflush(fd);
3727  fprintf(fd,"\n\tif (soap->error)");
3728  fprintf(fd,"\n\t{\tif (soap->error == SOAP_TAG_MISMATCH && soap->level == 2)\n\t\t\treturn soap_recv_fault(soap);");
3729  fprintf(fd,"\n\t\treturn soap_closesock(soap);");
3730  fprintf(fd,"\n\t}");
3731  fprintf(fd,"\n\tif (soap_body_end_in(soap)");
3732  fprintf(fd,"\n\t || soap_envelope_end_in(soap)");
3733  fprintf(fd,"\n\t || soap_end_recv(soap))");
3734  fprintf(fd,"\n\t\treturn soap_closesock(soap);");
3735  if (!is_response(result->info.typ) && response)
3736  { if (result->info.typ->type == Tarray)
3737      fprintf(fd,"\n\tmemcpy(%s, soap_tmp_%s->%s", ident(result->sym->name), c_ident(response->info.typ), ident(result->sym->name));
3738    else if (result->info.typ->type == Treference)
3739      fprintf(fd,"\n\t%s = soap_tmp_%s->%s;", ident(result->sym->name), c_ident(response->info.typ), ident(result->sym->name));
3740    else if (!is_external(result->info.typ->ref))
3741    { fprintf(fd,"\n\tif (%s && soap_tmp_%s->%s)", ident(result->sym->name), c_ident(response->info.typ), ident(result->sym->name));
3742      fprintf(fd,"\n\t\t*%s = *soap_tmp_%s->%s;", ident(result->sym->name), c_ident(response->info.typ), ident(result->sym->name));
3743    }
3744  }
3745  fprintf(fd,"\n\treturn soap_closesock(soap);");
3746  fprintf(fd ,"\n}");
3747  fflush(fd);
3748}
3749
3750void
3751gen_serve_method(FILE *fd, Table *table, Entry *param, char *name)
3752{ Service *sp = NULL;
3753  char *style, *encoding;
3754  Entry *q,*pin, *pout, *response = NULL;
3755  Table *input;
3756  char *xtag;
3757  Method *m;
3758  char *method_style = NULL, *method_encoding = NULL, *method_response_encoding = NULL;
3759  q = entry(table, param->sym);
3760  if (!q)
3761    execerror("no table entry");
3762  pout = (Entry*)q->info.typ->ref;
3763  if (!is_response(pout->info.typ))
3764    response = get_response(param->info.typ);
3765  if (name)
3766    fprintf(fd, "\n\nstatic int serve_%s(%s *soap)", ident(param->sym->name), name);
3767  else
3768  { fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_serve_%s(struct soap*);", ident(param->sym->name));
3769    fprintf(fd, "\n\nSOAP_FMAC5 int SOAP_FMAC6 soap_serve_%s(struct soap *soap)", ident(param->sym->name));
3770  }
3771  fprintf(fd, "\n{\tstruct %s soap_tmp_%s;", ident(param->sym->name), ident(param->sym->name));
3772  for (sp = services; sp; sp = sp->next)
3773    if (has_ns_eq(sp->ns, param->sym->name))
3774    { style = sp->style;
3775      encoding = sp->encoding;
3776      method_style = style;
3777      method_encoding = encoding;
3778      method_response_encoding = NULL;
3779      for (m = sp->list; m; m = m->next)
3780      { if (is_eq_nons(m->name, param->sym->name))
3781	{ if (m->mess == ENCODING)
3782	    method_encoding = m->part;
3783	  else if (m->mess == RESPONSE_ENCODING)
3784	    method_response_encoding = m->part;
3785	  else if (m->mess == STYLE)
3786	    method_style = m->part;
3787        }
3788      }
3789      break;
3790    }
3791  if (!method_response_encoding)
3792    method_response_encoding = method_encoding;
3793  fflush(fd);
3794  if (!is_transient(pout->info.typ))
3795  { if (pout->info.typ->type == Tarray)
3796    { fprintf(fd,"\n\tstruct %s soap_tmp_%s;", c_ident(response->info.typ), c_ident(response->info.typ));
3797      fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", c_ident(response->info.typ), c_ident(response->info.typ));
3798    }
3799    else if (((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && (is_external(pout->info.typ->ref) || is_volatile(pout->info.typ->ref) || is_typedef(pout->info.typ->ref)) && !is_dynamic_array(pout->info.typ->ref))
3800    { fprintf(fd, "\n\t%s;", c_type_id((Tnode*)pout->info.typ->ref, pout->sym->name));
3801      fprintf(fd,"\n\tsoap_default_%s(soap, &%s);", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name));
3802    }
3803    else if (((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3804    { fprintf(fd, "\n\t%s;", c_type_id((Tnode*)pout->info.typ->ref, pout->sym->name));
3805      fprintf(fd,"\n\t%s.soap_default(soap);", ident(pout->sym->name));
3806    }
3807    else if (((Tnode *)pout->info.typ->ref)->type == Tstruct && !is_dynamic_array(pout->info.typ->ref))
3808    { fprintf(fd, "\n\t%s;", c_type_id((Tnode*)pout->info.typ->ref, pout->sym->name));
3809      fprintf(fd,"\n\tsoap_default_%s(soap, &%s);", c_ident((Tnode *)pout->info.typ->ref), ident(pout->sym->name));
3810    }
3811    else if (pout->info.typ->type == Tpointer && !is_stdstring(pout->info.typ) && !is_stdwstring(pout->info.typ) && response)
3812    { fprintf(fd,"\n\tstruct %s soap_tmp_%s;", c_ident(response->info.typ), c_ident(response->info.typ));
3813      fprintf(fd,"\n\t%s soap_tmp_%s;", c_type(pout->info.typ->ref), c_ident(pout->info.typ->ref));
3814      fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", c_ident(response->info.typ), c_ident(response->info.typ));
3815      if (((Tnode*)pout->info.typ->ref)->type == Tclass && !is_external(pout->info.typ->ref) && !is_volatile(pout->info.typ->ref) && !is_typedef(pout->info.typ->ref))
3816        fprintf(fd,"\n\tsoap_tmp_%s.soap_default(soap);", c_ident(pout->info.typ->ref));
3817      else if (((Tnode*)pout->info.typ->ref)->type == Tpointer)
3818        fprintf(fd,"\n\tsoap_tmp_%s = NULL;", c_ident(pout->info.typ->ref));
3819      else
3820        fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", c_ident(pout->info.typ->ref), c_ident(pout->info.typ->ref));
3821      fprintf(fd,"\n\tsoap_tmp_%s.%s = &soap_tmp_%s;", c_ident(response->info.typ), ident(pout->sym->name), c_ident(pout->info.typ->ref));
3822    }
3823    else if (response)
3824    { fprintf(fd,"\n\tstruct %s soap_tmp_%s;", c_ident(response->info.typ), c_ident(response->info.typ));
3825      fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", c_ident(response->info.typ), c_ident(response->info.typ));
3826    }
3827    else
3828    { fprintf(fd,"\n\t%s soap_tmp_%s;", c_type(pout->info.typ->ref), c_ident(pout->info.typ->ref));
3829      if (is_string(pout->info.typ->ref) || is_wstring(pout->info.typ->ref))
3830        fprintf(fd,"\n\tsoap_tmp_%s = NULL;", c_ident(pout->info.typ->ref));
3831      else
3832        fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", c_ident(pout->info.typ->ref), c_ident(pout->info.typ->ref));
3833    }
3834  }
3835  fprintf(fd,"\n\tsoap_default_%s(soap, &soap_tmp_%s);", ident(param->sym->name), ident(param->sym->name));
3836  fflush(fd);
3837  if (sp && sp->URI && method_response_encoding)
3838  {     if (is_literal(method_response_encoding))
3839          fprintf(fd, "\n\tsoap->encodingStyle = NULL;");
3840        else if (sp->encoding)
3841          fprintf(fd, "\n\tsoap->encodingStyle = \"%s\";", sp->encoding);
3842	else if (method_response_encoding)
3843	  fprintf(fd, "\n\tsoap->encodingStyle = \"%s\";", method_response_encoding);
3844        else if (!eflag)
3845          fprintf(fd, "\n\tsoap->encodingStyle = NULL;");
3846  }
3847  else if (!eflag)
3848    fprintf(fd, "\n\tsoap->encodingStyle = NULL;");
3849  fprintf(fd,"\n\tif (!soap_get_%s(soap, &soap_tmp_%s, \"%s\", NULL))", ident(param->sym->name), ident(param->sym->name), ns_convert(param->sym->name));
3850  fprintf(fd,"\n\t\treturn soap->error;");
3851  fprintf(fd,"\n\tif (soap_body_end_in(soap)");
3852  fprintf(fd,"\n\t || soap_envelope_end_in(soap)");
3853  fprintf(fd,"\n\t || soap_end_recv(soap))\n\t\treturn soap->error;");
3854  if (name)
3855    fprintf(fd, "\n\tsoap->error = soap->%s(", ns_cname(param->sym->name, NULL));
3856  else
3857    fprintf(fd, "\n\tsoap->error = %s(soap", ident(param->sym->name));
3858  fflush(fd);
3859  q=entry(classtable, param->sym);
3860  input=(Table*) q->info.typ->ref;
3861  for (pin = input->list; pin; pin = pin->next)
3862    fprintf(fd, "%ssoap_tmp_%s.%s", !name || pin != input->list ? ", " : "", ident(param->sym->name), ident(pin->sym->name));
3863  if (is_transient(pout->info.typ))
3864    fprintf(fd, ");");
3865  else
3866  { if (!name || input->list)
3867      fprintf(fd, ", ");
3868    if (pout->info.typ->type == Tarray)
3869      fprintf(fd, "soap_tmp_%s.%s);", c_ident(response->info.typ), ident(pout->sym->name));
3870    else if (pout->info.typ->type == Treference && (((Tnode*)pout->info.typ->ref)->type == Tstruct || ((Tnode*)pout->info.typ->ref)->type == Tclass) && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3871      fprintf(fd, "%s);", ident(pout->sym->name));
3872    else if ((((Tnode*)pout->info.typ->ref)->type == Tstruct || ((Tnode*)pout->info.typ->ref)->type == Tclass) && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3873      fprintf(fd, "&%s);", ident(pout->sym->name));
3874    else if(pout->info.typ->type == Treference && response)
3875      fprintf(fd, "soap_tmp_%s.%s);", c_ident(response->info.typ), ident(pout->sym->name));
3876    else if(pout->info.typ->type == Treference)
3877      fprintf(fd, "soap_tmp_%s);", c_ident(pout->info.typ->ref));
3878    else
3879      fprintf(fd, "&soap_tmp_%s);", c_ident(pout->info.typ->ref));
3880  }
3881  fprintf(fd,"\n\tif (soap->error)\n\t\treturn soap->error;");
3882
3883  if (!is_transient(pout->info.typ))
3884  { fprintf(fd,"\n\tsoap_serializeheader(soap);");
3885    if (pout->info.typ->type == Tarray)
3886      fprintf(fd, "\n\tsoap_serialize_%s(soap, &soap_tmp_%s);", c_ident(response->info.typ), c_ident(response->info.typ));
3887    else if (((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && (is_external(pout->info.typ->ref) || is_volatile(pout->info.typ->ref) || is_typedef(pout->info.typ->ref)) && !is_dynamic_array(pout->info.typ->ref))
3888      fprintf(fd, "\n\tsoap_serialize_%s(soap, &%s);", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name));
3889    else if(((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3890      fprintf(fd, "\n\t%s.soap_serialize(soap);", ident(pout->sym->name));
3891    else if(((Tnode *)pout->info.typ->ref)->type == Tstruct && !is_dynamic_array(pout->info.typ->ref))
3892      fprintf(fd, "\n\tsoap_serialize_%s(soap, &%s);", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name));
3893    else if (response)
3894      fprintf(fd, "\n\tsoap_serialize_%s(soap, &soap_tmp_%s);", c_ident(response->info.typ), c_ident(response->info.typ));
3895    else if (!is_XML(pout->info.typ->ref))
3896      fprintf(fd, "\n\tsoap_serialize_%s(soap, &soap_tmp_%s);", c_ident(pout->info.typ->ref), c_ident(pout->info.typ->ref));
3897    if (has_ns_eq(NULL, pout->sym->name))
3898      xtag = ns_convert(pout->sym->name);
3899    else
3900      xtag = xml_tag(pout->info.typ);
3901    fprintf(fd, "\n\tif (soap_begin_count(soap))\n\t\treturn soap->error;");
3902    fprintf(fd, "\n\tif (soap->mode & SOAP_IO_LENGTH)");
3903    fprintf(fd, "\n\t{\tif (soap_envelope_begin_out(soap)");
3904    fprintf(fd,"\n\t\t || soap_putheader(soap)");
3905    fprintf(fd,"\n\t\t || soap_body_begin_out(soap)");
3906    if (pout->info.typ->type == Tarray)
3907      fprintf(fd,"\n\t\t || soap_put_%s(soap, &soap_tmp_%s.%s, \"%s\", \"\")", c_ident(response->info.typ), c_ident(response->info.typ), pout->sym->name, xtag);
3908    else if (((Tnode*)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && (is_external(pout->info.typ->ref) || is_volatile(pout->info.typ->ref) || is_typedef(pout->info.typ->ref)) && !is_dynamic_array(pout->info.typ->ref))
3909      fprintf(fd, "\n\t\t || soap_put_%s(soap, &%s, \"%s\", \"\")", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name), ns_convert(pout->sym->name));
3910    else if (((Tnode*)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3911      fprintf(fd, "\n\t\t || %s.soap_put(soap, \"%s\", \"\")", ident(pout->sym->name), xtag);
3912    else if (((Tnode*)pout->info.typ->ref)->type == Tstruct && !is_dynamic_array(pout->info.typ->ref))
3913      fprintf(fd, "\n\t\t || soap_put_%s(soap, &%s, \"%s\", \"\")", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name), xtag);
3914    else if (response)
3915      fprintf(fd,"\n\t\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", c_ident(response->info.typ), c_ident(response->info.typ), xml_tag(response->info.typ));
3916    else if (is_XML(pout->info.typ->ref) && is_string(pout->info.typ->ref))
3917      fprintf(fd,"\n\t\t || soap_outliteral(soap, \"%s\", &soap_tmp_%s, NULL)", ns_convert(pout->sym->name), c_ident(pout->info.typ->ref));
3918    else if (is_XML(pout->info.typ->ref) && is_wstring(pout->info.typ->ref))
3919      fprintf(fd,"\n\t\t || soap_outwliteral(soap, \"%s\", &soap_tmp_%s, NULL)", ns_convert(pout->sym->name), c_ident(pout->info.typ->ref));
3920    else
3921      fprintf(fd,"\n\t\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", c_ident(pout->info.typ), c_ident(pout->info.typ->ref), ns_convert(pout->sym->name));
3922    fprintf(fd,"\n\t\t || soap_body_end_out(soap)");
3923    fprintf(fd,"\n\t\t || soap_envelope_end_out(soap))");
3924    fprintf(fd,"\n\t\t\t return soap->error;");
3925    fprintf(fd,"\n\t};");
3926    fprintf(fd,"\n\tif (soap_end_count(soap)");
3927    fprintf(fd,"\n\t || soap_response(soap, SOAP_OK)");
3928    fprintf(fd,"\n\t || soap_envelope_begin_out(soap)");
3929    fprintf(fd,"\n\t || soap_putheader(soap)");
3930    fprintf(fd,"\n\t || soap_body_begin_out(soap)");
3931    if (pout->info.typ->type == Tarray)
3932      fprintf(fd,"\n\t || soap_put_%s(soap, &soap_tmp_%s.%s, \"%s\", \"\")", c_ident(response->info.typ), c_ident(response->info.typ), ident(pout->sym->name), xtag);
3933    else if (((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && (is_external(pout->info.typ->ref) || is_volatile(pout->info.typ->ref) || is_typedef(pout->info.typ->ref)) && !is_dynamic_array(pout->info.typ->ref))
3934      fprintf(fd, "\n\t || soap_put_%s(soap, &%s, \"%s\", \"\")", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name), ns_convert(pout->sym->name));
3935    else if(((Tnode *)pout->info.typ->ref)->type == Tclass && !is_stdstring(pout->info.typ->ref) && !is_stdwstring(pout->info.typ->ref) && !is_dynamic_array(pout->info.typ->ref))
3936      fprintf(fd, "\n\t || %s.soap_put(soap, \"%s\", \"\")", ident(pout->sym->name), xtag);
3937    else if(((Tnode *)pout->info.typ->ref)->type == Tstruct && !is_dynamic_array(pout->info.typ->ref))
3938      fprintf(fd, "\n\t || soap_put_%s(soap, &%s, \"%s\", \"\")", c_ident((Tnode*)pout->info.typ->ref), ident(pout->sym->name), xtag);
3939    else if (response)
3940      fprintf(fd,"\n\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", c_ident(response->info.typ), c_ident(response->info.typ), xml_tag(response->info.typ));
3941    else if (is_XML(pout->info.typ->ref) && is_string(pout->info.typ->ref))
3942      fprintf(fd,"\n\t || soap_outliteral(soap, \"%s\", &soap_tmp_%s, NULL)", ns_convert(pout->sym->name), c_ident(pout->info.typ->ref));
3943    else if (is_XML(pout->info.typ->ref) && is_wstring(pout->info.typ->ref))
3944      fprintf(fd,"\n\t || soap_outwliteral(soap, \"%s\", &soap_tmp_%s, NULL)", ns_convert(pout->sym->name), c_ident(pout->info.typ->ref));
3945    else
3946      fprintf(fd,"\n\t || soap_put_%s(soap, &soap_tmp_%s, \"%s\", \"\")", c_ident(pout->info.typ), c_ident(pout->info.typ->ref), ns_convert(pout->sym->name));
3947    fprintf(fd,"\n\t || soap_body_end_out(soap)");
3948    fprintf(fd,"\n\t || soap_envelope_end_out(soap)");
3949    fprintf(fd,"\n\t || soap_end_send(soap))");
3950    fprintf(fd, "\n\t\treturn soap->error;");
3951  }
3952  fprintf(fd,"\n\treturn soap_closesock(soap);");
3953  fprintf(fd,"\n}");
3954  fflush(fd);
3955}
3956
3957void
3958gen_object_code(FILE *fd, Table *table, Symbol *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
3959{ Entry *p, *method, *catch_method, *param;
3960  Table *t;
3961  fprintf(fd, "\n\n#include \"%s%s.h\"", prefix, name);
3962  if (namespaceid)
3963    fprintf(fd,"\n\nnamespace %s {", namespaceid);
3964  fprintf(fd, "\n\n%s::%s()\n{\t%s_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);\n}", name, name, name);
3965  fprintf(fd, "\n\n%s::%s(const struct soap &soap)\n{\tsoap_copy_context(this, &soap);\n\t%s_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);\n}", name, name, name);
3966  fprintf(fd, "\n\n%s::%s(soap_mode iomode)\n{\t%s_init(iomode, iomode);\n}", name, name, name);
3967  fprintf(fd, "\n\n%s::%s(soap_mode imode, soap_mode omode)\n{\t%s_init(imode, omode);\n}", name, name, name);
3968  fprintf(fd, "\n\n%s::~%s()\n{ }", name, name);
3969  fprintf(fd, "\n\nvoid %s::%s_init(soap_mode imode, soap_mode omode)\n{\tstatic const struct Namespace namespaces[] =\n", name, name);
3970  gen_nsmap(fd, ns, URI);
3971  fprintf(fd, "\tsoap_imode(this, imode);\n\tsoap_omode(this, omode);");
3972  if (nflag)
3973    fprintf(fd, "\n\tthis->namespaces = namespaces;\n};");
3974  else
3975    fprintf(fd, "\n\tif (!this->namespaces)\n\t\tthis->namespaces = namespaces;\n};");
3976  fprintf(fd, "\n\n%s *%s::copy()\n{\t%s *dup = new %s(*(struct soap*)this);\n\treturn dup;\n}", name, name, name, name);
3977  fprintf(fd, "\n\nint %s::soap_close_socket()\n{\treturn soap_closesock(this);\n}", name);
3978  fprintf(fd, "\n\nint %s::soap_senderfault(const char *string, const char *detailXML)\n{\treturn ::soap_sender_fault(this, string, detailXML);\n}", name);
3979  fprintf(fd, "\n\nint %s::soap_senderfault(const char *subcodeQName, const char *string, const char *detailXML)\n{\treturn ::soap_sender_fault_subcode(this, subcodeQName, string, detailXML);\n}", name);
3980  fprintf(fd, "\n\nint %s::soap_receiverfault(const char *string, const char *detailXML)\n{\treturn ::soap_receiver_fault(this, string, detailXML);\n}", name);
3981  fprintf(fd, "\n\nint %s::soap_receiverfault(const char *subcodeQName, const char *string, const char *detailXML)\n{\treturn ::soap_receiver_fault_subcode(this, subcodeQName, string, detailXML);\n}", name);
3982  fprintf(fd, "\n\nvoid %s::soap_print_fault(FILE *fd)\n{\t::soap_print_fault(this, fd);\n}", name);
3983  fprintf(fd, "\n\n#ifndef WITH_LEAN\nvoid %s::soap_stream_fault(std::ostream& os)\n{\t::soap_stream_fault(this, os);\n}", name);
3984  fprintf(fd, "\n\nchar *%s::soap_sprint_fault(char *buf, size_t len)\n{\treturn ::soap_sprint_fault(this, buf, len);\n}\n#endif", name);
3985  fprintf(fd, "\n\nvoid %s::soap_noheader()\n{\theader = NULL;\n}", name);
3986  p = entry(classtable, lookup("SOAP_ENV__Header"));
3987  if (p)
3988  { t = p->info.typ->ref;
3989    if (t && t->list && !is_void(t->list->info.typ))
3990    { fprintf(fd, "\n\nvoid %s::soap_header(", name);
3991      gen_params(fd, t, NULL, 0);
3992      fprintf(fd, "\n{\t::soap_header(this);");
3993      for (param = t->list; param; param = param->next)
3994      { if (namespaceid)
3995          fprintf(fd, "\n\t((%s::SOAP_ENV__Header*)this->header)->%s = %s;", namespaceid, ident(param->sym->name), ident(param->sym->name));
3996        else
3997          fprintf(fd, "\n\tthis->header->%s = %s;", ident(param->sym->name), ident(param->sym->name));
3998      }
3999      fprintf(fd, "\n}");
4000      if (namespaceid)
4001        fprintf(fd, "\n\nconst SOAP_ENV__Header *%s::soap_header()\n{\treturn (const %s::SOAP_ENV__Header*)this->header;\n}", name, namespaceid);
4002      else
4003        fprintf(fd, "\n\nconst SOAP_ENV__Header *%s::soap_header()\n{\treturn this->header;\n}", name);
4004    }
4005  }
4006  fprintf(fd, "\n\nint %s::run(int port)\n{\tif (soap_valid_socket(bind(NULL, port, 100)))\n\t{\tfor (;;)\n\t\t{\tif (!soap_valid_socket(accept()))\n\t\t\t\treturn this->error;\n\t\t\t(void)serve();\n\t\t\tsoap_destroy(this);\n\t\t\tsoap_end(this);\n\t\t}\n\t}\n\telse\n\t\treturn this->error;\n\treturn SOAP_OK;\n}", name);
4007  fprintf(fd, "\n\nSOAP_SOCKET %s::bind(const char *host, int port, int backlog)\n{\treturn soap_bind(this, host, port, backlog);\n}", name);
4008  fprintf(fd, "\n\nSOAP_SOCKET %s::accept()\n{\treturn soap_accept(this);\n}", name);
4009  fprintf(fd, "\n\nint %s::serve()", name);
4010  fprintf(fd, "\n{\n#ifndef WITH_FASTCGI\n\tunsigned int k = this->max_keep_alive;\n#endif\n\tdo\n\t{\tsoap_begin(this);");
4011  fprintf(fd,"\n#ifdef WITH_FASTCGI\n\t\tif (FCGI_Accept() < 0)\n\t\t{\n\t\t\tthis->error = SOAP_EOF;\n\t\t\treturn soap_send_fault(this);\n\t\t}\n#endif"
4012);
4013  fprintf(fd,"\n\n\t\tsoap_begin(this);");
4014
4015  fprintf(fd,"\n\n#ifndef WITH_FASTCGI\n\t\tif (this->max_keep_alive > 0 && !--k)\n\t\t\tthis->keep_alive = 0;\n#endif");
4016  fprintf(fd,"\n\n\t\tif (soap_begin_recv(this))\n\t\t{\tif (this->error < SOAP_STOP)\n\t\t\t{\n#ifdef WITH_FASTCGI\n\t\t\t\tsoap_send_fault(this);\n#else \n\t\t\t\treturn soap_send_fault(this);\n#endif\n\t\t\t}\n\t\t\tsoap_closesock(this);\n\n\t\t\tcontinue;\n\t\t}");
4017  fprintf(fd,"\n\n\t\tif (soap_envelope_begin_in(this)\n\t\t || soap_recv_header(this)\n\t\t || soap_body_begin_in(this)\n\t\t || dispatch() || (this->fserveloop && this->fserveloop(this)))\n\t\t{\n#ifdef WITH_FASTCGI\n\t\t\tsoap_send_fault(this);\n#else\n\t\t\treturn soap_send_fault(this);\n#endif\n\t\t}");
4018  fprintf(fd,"\n\n#ifdef WITH_FASTCGI\n\t\tsoap_destroy(this);\n\t\tsoap_end(this);\n\t} while (1);\n#else\n\t} while (this->keep_alive);\n#endif");
4019
4020  fprintf(fd, "\n\treturn SOAP_OK;");
4021  fprintf(fd, "\n}\n");
4022  for (method = table->list; method; method = method->next)
4023    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && has_ns_eq(ns->name, method->sym->name))
4024      fprintf(fd, "\nstatic int serve_%s(%s*);", ident(method->sym->name), name);
4025  fprintf(fd, "\n\nint %s::dispatch()", name);
4026  fprintf(fd, "\n{\tif (soap_peek_element(this))\n\t\treturn this->error;");
4027  catch_method = NULL;
4028  for (method = table->list; method; method = method->next)
4029  { char *action = NULL;
4030    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && has_ns_eq(ns->name, method->sym->name))
4031    { if (aflag)
4032      { Service *sp;
4033        for (sp = services; sp; sp = sp->next)
4034        { if (has_ns_eq(sp->ns, method->sym->name))
4035	  { Method *m;
4036	    for (m = sp->list; m; m = m->next)
4037	    { if (is_eq_nons(m->name, method->sym->name))
4038	      { if (m->mess == ACTION)
4039	          action = m->part;
4040	      }
4041	    }
4042  	  }
4043        }
4044      }
4045      if (is_invisible(method->sym->name))
4046      { Entry *param = entry(classtable, method->sym);
4047        if (param)
4048        { param = ((Table*)param->info.typ->ref)->list;
4049          if (param)
4050          { if (action)
4051              if (*action == '"')
4052	        fprintf(fd, "\n\tif ((!this->action && !soap_match_tag(this, this->tag, \"%s\")) || (this->action && !strcmp(this->action, %s))", ns_convert(param->sym->name), action);
4053              else
4054	        fprintf(fd, "\n\tif ((!this->action && !soap_match_tag(this, this->tag, \"%s\")) || (this->action && !strcmp(this->action, \"%s\"))", ns_convert(param->sym->name), action);
4055	    else
4056              fprintf(fd, "\n\tif (!soap_match_tag(this, this->tag, \"%s\")", ns_convert(param->sym->name));
4057            fprintf(fd, ")\n\t\treturn serve_%s(this);", ident(method->sym->name));
4058          }
4059        }
4060	else
4061	  catch_method = method;
4062      }
4063      else
4064      { if (action)
4065          if (*action == '"')
4066	    fprintf(fd, "\n\tif ((!this->action && !soap_match_tag(this, this->tag, \"%s\")) || (this->action && !strcmp(this->action, %s))", ns_convert(method->sym->name), action);
4067          else
4068	    fprintf(fd, "\n\tif ((!this->action && !soap_match_tag(this, this->tag, \"%s\")) || (this->action && !strcmp(this->action, \"%s\"))", ns_convert(method->sym->name), action);
4069	else
4070          fprintf(fd, "\n\tif (!soap_match_tag(this, this->tag, \"%s\")", ns_convert(method->sym->name));
4071        fprintf(fd, ")\n\t\treturn serve_%s(this);", ident(method->sym->name));
4072      }
4073    }
4074  }
4075  if (catch_method)
4076    fprintf(fd, "\n\treturn serve_%s(this);", ident(catch_method->sym->name));
4077  else
4078    fprintf(fd, "\n\treturn this->error = SOAP_NO_METHOD;\n}");
4079  for (method = table->list; method; method = method->next)
4080    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && !is_imported(method->info.typ) && has_ns_eq(ns->name, method->sym->name))
4081      gen_serve_method(fd, table, method, name);
4082  if (namespaceid)
4083    fprintf(fd,"\n\n} // namespace %s\n", namespaceid);
4084  fprintf(fd,"\n/* End of server object code */\n");
4085}
4086
4087void
4088gen_response_begin(FILE *fd, int n, char *s)
4089{ if (!is_invisible(s))
4090    fprintf(fd, "%*s<%sResponse>\n", n, "", s);
4091}
4092
4093void
4094gen_response_end(FILE *fd, int n, char *s)
4095{ if (!is_invisible(s))
4096    fprintf(fd, "%*s</%sResponse>\n", n, "", s);
4097}
4098
4099void
4100gen_element_begin(FILE *fd, int n, char *s, char *t)
4101{ if (!is_invisible(s))
4102  { if (tflag && t && *t)
4103      fprintf(fd, "%*s<%s xsi:type=\"%s\"", n, "", s, t);
4104    else
4105      fprintf(fd, "%*s<%s", n, "", s);
4106  }
4107}
4108
4109void
4110gen_element_end(FILE *fd, int n, char *s)
4111{ if (!is_invisible(s))
4112    fprintf(fd, "%*s</%s>\n", n, "", s);
4113  else
4114    fprintf(fd, "\n");
4115}
4116
4117void
4118gen_data(char *buf, Table *t, char *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
4119{ Entry *p, *q, *r;
4120  FILE *fd;
4121  char *method_encoding = NULL;
4122  char *method_response_encoding = NULL;
4123  if (t)
4124  { for (p = t->list; p; p = p->next)
4125      if (p->info.typ->type == Tfun && !(p->info.sto & Sextern) && has_ns_eq(ns, p->sym->name))
4126      { Service *sp;
4127        Method *m;
4128	char *nse = ns_qualifiedElement(p->info.typ);
4129	char *nsa = ns_qualifiedAttribute(p->info.typ);
4130        method_encoding = encoding;
4131	method_response_encoding = NULL;
4132	for (sp = services; sp; sp = sp->next)
4133	{ if (!tagcmp(sp->ns, ns))
4134	  { for (m = sp->list; m; m = m->next)
4135	    { if (is_eq_nons(m->name, p->sym->name))
4136              { if (m->mess == ENCODING)
4137	          method_encoding = m->part;
4138                else if (m->mess == RESPONSE_ENCODING)
4139	          method_response_encoding = m->part;
4140	      }
4141	    }
4142	  }
4143	}
4144	if (!method_response_encoding)
4145	  method_response_encoding = method_encoding;
4146	/* request */
4147        fd = gen_env(buf, ns_remove(p->sym->name), 0, t, ns, name, URL, executable, URI, method_encoding);
4148	if (!fd)
4149	  return;
4150  	q = entry(classtable, p->sym);
4151	gen_element_begin(fd, 2, ns_convert(p->sym->name), NULL);
4152  	if (q)
4153	{ if (!is_invisible(p->sym->name))
4154	  { gen_atts(fd, q->info.typ->ref, nsa);
4155            fprintf(fd, "\n");
4156	  }
4157	  for (q = ((Table*)q->info.typ->ref)->list; q; q = q->next)
4158	    gen_field(fd, 3, q, nse, nsa, method_encoding);
4159	}
4160        gen_element_end(fd, 2, ns_convert(p->sym->name));
4161        fprintf(fd, " </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n");
4162        fclose(fd);
4163	/* response */
4164	q = (Entry*)p->info.typ->ref;
4165	if (q && !is_transient(q->info.typ))
4166        { fd = gen_env(buf, ns_remove(p->sym->name), 1, t, ns, name, URL, executable, URI, method_response_encoding);
4167	  if (!fd)
4168	    return;
4169	  if (q && !is_response(q->info.typ))
4170	    if (is_XML(q->info.typ->ref))
4171	    { gen_response_begin(fd, 2, ns_convert(p->sym->name));
4172	      gen_response_end(fd, 2, ns_convert(p->sym->name));
4173	    }
4174	    else
4175	    { gen_response_begin(fd, 2, ns_convert(p->sym->name));
4176	      gen_field(fd, 3, q, nse, nsa, method_response_encoding);
4177	      gen_response_end(fd, 2, ns_convert(p->sym->name));
4178	    }
4179          else if (q && q->info.typ->ref && ((Tnode*)q->info.typ->ref)->ref)
4180          { char *xtag;
4181	    nse = ns_qualifiedElement(q->info.typ->ref);
4182	    nsa = ns_qualifiedAttribute(q->info.typ->ref);
4183	    if (has_ns_eq(NULL, q->sym->name))
4184              xtag = q->sym->name;
4185            else
4186              xtag = ((Tnode*)q->info.typ->ref)->id->name;
4187	    gen_element_begin(fd, 2, ns_add(xtag, nse), NULL);
4188	    if (!is_invisible(xtag))
4189	    { gen_atts(fd, ((Tnode*)q->info.typ->ref)->ref, nsa);
4190              fprintf(fd, "\n");
4191	    }
4192	    for (r = ((Table*)((Tnode*)q->info.typ->ref)->ref)->list; r; r = r->next)
4193	      gen_field(fd, 3, r, nse, nsa, method_response_encoding);
4194	    gen_element_end(fd, 2, ns_add(xtag, nse));
4195	  }
4196          fflush(fd);
4197          fprintf(fd, " </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n");
4198          fclose(fd);
4199	}
4200      }
4201  }
4202}
4203
4204void
4205gen_field(FILE *fd, int n, Entry *p, char *nse, char *nsa, char *encoding)
4206{ Entry *q;
4207  char tmp[32];
4208  int i, d;
4209  if (!(p->info.sto & Sattribute) && !is_transient(p->info.typ) && p->info.typ->type != Tfun && strncmp(p->sym->name, "__size", 6) && strncmp(p->sym->name, "__type", 6) && strncmp(p->sym->name, "__union", 7))
4210  { if (is_soap12(encoding) && (p->info.sto & Sreturn) && (nse || has_ns_eq(NULL, p->sym->name)) && !is_literal(encoding))
4211      fprintf(fd, "%*s<SOAP-RPC:result xmlns:SOAP-RPC=\"%s\">%s</SOAP-RPC:result>\n", n, "", rpcURI, ns_add(p->sym->name, nse));
4212    if (is_XML(p->info.typ))
4213    { gen_element_begin(fd, n, ns_add(p->sym->name, nse), NULL);
4214      if (!is_invisible(p->sym->name))
4215        fprintf(fd, ">");
4216      else
4217        fprintf(fd, "%*s<!-- extensibility element(s) -->\n", n, "");
4218      gen_element_end(fd, n, ns_add(p->sym->name, nse));
4219    }
4220    else
4221    { if (!is_string(p->info.typ) && n >= 10 && (p->info.typ->type == Tpointer || p->info.typ->type == Treference))
4222      { if (!is_invisible(p->sym->name))
4223        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), NULL);
4224          fprintf(fd, " xsi:nil=\"true\">");
4225        }
4226      }
4227      else if (p->info.typ->type == Tarray)
4228      { i = ((Tnode*) p->info.typ->ref)->width;
4229        if (i)
4230        { i = p->info.typ->width / i;
4231          if (i > 100)
4232            i = 100;
4233	}
4234	gen_element_begin(fd, n, ns_add(p->sym->name, nse), "SOAP-ENC:Array");
4235	fprintf(fd, " SOAP-ENC:arrayType=\"%s[%d]\">", xsi_type_Tarray(p->info.typ), i);
4236        fflush(fd);
4237	gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4238      }
4239      else if (is_dynamic_array(p->info.typ) && !is_binary(p->info.typ))
4240      { if (!eflag && (has_ns(p->info.typ) || is_untyped(p->info.typ)))
4241        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), xsi_type(p->info.typ));
4242          gen_atts(fd, p->info.typ->ref, nsa);
4243	}
4244        else
4245	{ d = get_Darraydims(p->info.typ);
4246	  if (d)
4247	  { for (i = 0; i < d-1; i++)
4248	    { tmp[2*i] = ',';
4249	      tmp[2*i+1] = '1';
4250	    }
4251	    tmp[2*d-2] = '\0';
4252	  }
4253	  else
4254	    *tmp = '\0';
4255	  gen_element_begin(fd, n, ns_add(p->sym->name, nse), "SOAP-ENC:Array");
4256	  if (((Table*)p->info.typ->ref)->list->info.minOccurs > 1)
4257	    fprintf(fd, " SOAP-ENC:arrayType=\"%s[%ld%s]\">", wsdl_type(((Table*)p->info.typ->ref)->list->info.typ, ""), ((Table*)p->info.typ->ref)->list->info.minOccurs, tmp);
4258	  else
4259	    fprintf(fd, " SOAP-ENC:arrayType=\"%s[1%s]\">", wsdl_type(((Table*)p->info.typ->ref)->list->info.typ, ""), tmp);
4260	}
4261        fflush(fd);
4262        gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4263      }
4264      else if ((p->info.typ->type == Tpointer || p->info.typ->type == Treference) && is_dynamic_array(p->info.typ->ref) && !is_binary(p->info.typ->ref))
4265      { if (!eflag && (has_ns(p->info.typ->ref) || is_untyped(p->info.typ->ref)))
4266        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), xsi_type(p->info.typ->ref));
4267          gen_atts(fd, ((Tnode*)p->info.typ->ref)->ref, nsa);
4268	}
4269        else
4270	{ d = get_Darraydims(p->info.typ->ref);
4271	  if (d)
4272	  { for (i = 0; i < d-1; i++)
4273	    { tmp[2*i] = ',';
4274	      tmp[2*i+1] = '1';
4275	    }
4276	    tmp[2*d-2] = '\0';
4277	  }
4278	  else
4279	    *tmp = '\0';
4280	  gen_element_begin(fd, n, ns_add(p->sym->name, nse), "SOAP-ENC:Array");
4281	  if ((((Tnode*)p->info.typ->ref)->type == Tstruct || ((Tnode*)p->info.typ->ref)->type == Tclass) && ((Table*)((Tnode*)p->info.typ->ref)->ref)->list->info.minOccurs > 1)
4282	    fprintf(fd, " SOAP-ENC:arrayType=\"%s[%ld%s]\">", wsdl_type(((Table*)((Tnode*)p->info.typ->ref)->ref)->list->info.typ, ""), ((Table*)((Tnode*)p->info.typ->ref)->ref)->list->info.minOccurs, tmp);
4283	  else
4284	    fprintf(fd, " SOAP-ENC:arrayType=\"%s[1%s]\">", wsdl_type(((Table*)((Tnode*)p->info.typ->ref)->ref)->list->info.typ, ""), tmp);
4285	}
4286        fflush(fd);
4287        gen_val(fd, n, p->info.typ->ref, nse, nsa, encoding);
4288      }
4289      else if (p->info.typ->type == Tstruct || p->info.typ->type == Tclass)
4290      { /*
4291        if (!is_primclass(p->info.typ))
4292        { char *nse1 = ns_qualifiedElement(p->info.typ);
4293  	  char *nsa1 = ns_qualifiedAttribute(p->info.typ);
4294	  if (nse1)
4295	    nse = nse1;
4296	  if (nsa1)
4297	    nsa = nsa1;
4298	}
4299	*/
4300        if (!is_invisible(p->sym->name))
4301        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), xsi_type_u(p->info.typ));
4302          gen_atts(fd, p->info.typ->ref, nsa);
4303        }
4304	else if (is_anyType(p->info.typ))
4305          fprintf(fd, "%*s<!-- extensibility element(s) -->\n", n, "");
4306      }
4307      else if ((p->info.typ->type == Tpointer || p->info.typ->type == Treference)
4308             && (((Tnode*)p->info.typ->ref)->type == Tstruct || ((Tnode*)p->info.typ->ref)->type == Tclass))
4309      { /*
4310        if (!is_primclass(p->info.typ->ref))
4311        { char *nse1 = ns_qualifiedElement(p->info.typ->ref);
4312	  char *nsa1 = ns_qualifiedAttribute(p->info.typ->ref);
4313	  if (nse1)
4314	    nse = nse1;
4315	  if (nsa1)
4316	    nsa = nsa1;
4317	}
4318	*/
4319        if (!is_invisible(p->sym->name))
4320        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), xsi_type_u(p->info.typ));
4321          gen_atts(fd, ((Tnode*)p->info.typ->ref)->ref, nsa);
4322        }
4323	else if (is_anyType(p->info.typ))
4324          fprintf(fd, "%*s<!-- extensibility element(s) -->\n", n, "");
4325      }
4326      else if (p->info.typ->type != Tunion)
4327      { if (!is_invisible(p->sym->name))
4328        { gen_element_begin(fd, n, ns_add(p->sym->name, nse), xsi_type_u(p->info.typ));
4329	  if (p->info.typ->type == Ttemplate)
4330	  { if (((Tnode*)p->info.typ->ref)->type == Tpointer
4331	     && (((Tnode*)((Tnode*)p->info.typ->ref)->ref)->type == Tclass
4332	      || ((Tnode*)((Tnode*)p->info.typ->ref)->ref)->type == Tstruct))
4333              gen_atts(fd, ((Tnode*)((Tnode*)p->info.typ->ref)->ref)->ref, nsa);
4334	    else if (((Tnode*)p->info.typ->ref)->type == Tclass
4335	     || ((Tnode*)p->info.typ->ref)->type == Tstruct)
4336              gen_atts(fd, ((Tnode*)p->info.typ->ref)->ref, nsa);
4337	    else
4338	      fprintf(fd, ">");
4339	  }
4340	  else
4341	    fprintf(fd, ">");
4342        }
4343      }
4344      switch (p->info.typ->type)
4345      { case Tchar:
4346        case Tshort:
4347        case Tint:
4348        case Tlong:
4349        case Tllong:
4350        case Tuchar:
4351        case Tushort:
4352        case Tuint:
4353        case Tulong:
4354        case Tullong:
4355          if (p->info.hasval)
4356	    fprintf(fd, SOAP_LONG_FORMAT, p->info.val.i);
4357	  else
4358	    fprintf(fd, "0");
4359	  break;
4360        case Tfloat:
4361        case Tdouble:
4362        case Tldouble:
4363          if (p->info.hasval)
4364	    fprintf(fd, "%f", p->info.val.r);
4365	  else
4366	    fprintf(fd, "0.0");
4367          break;
4368        case Tenum:
4369	  if (p->info.hasval && p->info.typ->ref)
4370	  { for (q = ((Table*)p->info.typ->ref)->list; q; q = q->next)
4371	      if (p->info.val.i == q->info.val.i)
4372	      { fprintf(fd, "%s", ns_remove2(q->sym->name));
4373		break;
4374	      }
4375	  }
4376	  else
4377	    gen_val(fd, n+1, p->info.typ, nse, nsa, encoding);
4378	  break;
4379        case Tpointer:
4380        case Treference:
4381	  if (is_string(p->info.typ) || is_wstring(p->info.typ))
4382	  { if (p->info.hasval)
4383	      fprintf(fd, "%s", p->info.val.s);
4384	    else
4385	      gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4386	  }
4387	  else if (!is_dynamic_array(p->info.typ->ref) && n < 10)
4388	    gen_val(fd, n, p->info.typ->ref, nse, nsa, encoding);
4389	  break;
4390        case Tclass:
4391	  if (is_stdstr(p->info.typ))
4392	  { if (p->info.hasval)
4393	      fprintf(fd, "%s", p->info.val.s);
4394	    else
4395	      gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4396	    break;
4397	  }
4398        case Tstruct:
4399	  if (!is_dynamic_array(p->info.typ))
4400	    gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4401	  break;
4402        case Tunion:
4403	  gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4404	  break;
4405	case Ttemplate:
4406	  gen_val(fd, n, p->info.typ, nse, nsa, encoding);
4407	  break;
4408	default:
4409	  break;
4410        }
4411        if (p->info.typ->type != Tunion)
4412	  gen_element_end(fd, 0, ns_add(p->sym->name, nse));
4413        fflush(fd);
4414    }
4415  }
4416}
4417
4418void
4419gen_atts(FILE *fd, Table *p, char *nsa)
4420{ Entry *q, *r;
4421  int i;
4422  if (p)
4423  for (q = p->list; q; q = q->next)
4424    if (q->info.sto & Sattribute && !is_invisible(q->sym->name))
4425    { fprintf(fd, " %s=\"", ns_add(q->sym->name, nsa));
4426      switch (q->info.typ->type)
4427      { case Tchar:
4428        case Tshort:
4429        case Tint:
4430        case Tlong:
4431        case Tllong:
4432        case Tuchar:
4433        case Tushort:
4434        case Tuint:
4435        case Tulong:
4436        case Tullong:
4437          if (q->info.hasval)
4438	    fprintf(fd, SOAP_LONG_FORMAT, q->info.val.i);
4439          else
4440            fprintf(fd, "0");
4441          break;
4442        case Tfloat:
4443        case Tdouble:
4444        case Tldouble:
4445          if (q->info.hasval)
4446	    fprintf(fd, "%f", q->info.val.r);
4447	  else
4448	    fprintf(fd, "0.0");
4449          break;
4450        case Ttime:
4451	  break; /* should print value? */
4452        case Tenum:
4453	  if (q->info.hasval && q->info.typ->ref)
4454	  { for (r = ((Table*)q->info.typ->ref)->list; r; r = r->next)
4455	      if (r->info.val.i == q->info.val.i)
4456	      { fprintf(fd, "%s", ns_remove2(r->sym->name));
4457		break;
4458	      }
4459	  }
4460	  break;
4461        case Tpointer:
4462        case Treference:
4463	  if (is_string(q->info.typ))
4464	  { if (q->info.hasval)
4465	      fprintf(fd, "%s", q->info.val.s);
4466	    else if (q->info.typ->minLength > 0 && q->info.typ->minLength < 10000)
4467	      for (i = 0; i < q->info.typ->minLength; i++)
4468	        fprintf(fd, "X");
4469	  }
4470	  break;
4471        case Tclass:
4472	  if (is_stdstr(q->info.typ))
4473	  { if (q->info.hasval)
4474	      fprintf(fd, "%s", q->info.val.s);
4475	    else if (q->info.typ->minLength > 0 && q->info.typ->minLength < 10000)
4476	      for (i = 0; i < q->info.typ->minLength; i++)
4477	        fprintf(fd, "X");
4478          }
4479	  break;
4480	default:
4481	  break;
4482      }
4483      fprintf(fd, "\"");
4484    }
4485  fprintf(fd, ">");
4486  fflush(fd);
4487}
4488
4489void
4490gen_val(FILE *fd, int n, Tnode *p, char *nse, char *nsa, char *encoding)
4491{ Entry *q;
4492  int i;
4493  if (!is_transient(p) && p->type != Tfun && !is_XML(p))
4494  { if (p->type == Tarray)
4495    { i = ((Tnode*) p->ref)->width;
4496      if (i)
4497      { i = p->width / i;
4498        if (i > 100)
4499          i = 100;
4500        fprintf(fd, "\n");
4501        for (; i > 0; i--)
4502        { fprintf(fd, "%*s<item>", n+1, "");
4503          gen_val(fd, n+1, p->ref, nse, nsa, encoding);
4504          fprintf(fd, "</item>\n");
4505        }
4506        fprintf(fd, "%*s", n, "");
4507      }
4508    }
4509    else if (is_dynamic_array(p))
4510    { if (!is_binary(p))
4511      { Table *t;
4512        fprintf(fd, "\n");
4513	for (t = p->ref; t && !t->list; t = t->prev)
4514	  ;
4515        if (t)
4516	  gen_field(fd, n+1, t->list, nse, nsa, encoding);
4517        fprintf(fd, "%*s", n, "");
4518      }
4519    }
4520    switch (p->type)
4521    { case Tchar:
4522      case Tshort:
4523      case Tint:
4524      case Tlong:
4525      case Tllong:
4526      case Tuchar:
4527      case Tushort:
4528      case Tuint:
4529      case Tulong:
4530      case Tullong:
4531	fprintf(fd, "0");
4532	break;
4533      case Tfloat:
4534      case Tdouble:
4535      case Tldouble:
4536	fprintf(fd, "0.0");
4537        break;
4538      case Tenum:
4539        if (p->ref && (q = ((Table*)p->ref)->list))
4540          fprintf(fd, "%s", ns_remove(q->sym->name));
4541        else
4542          fprintf(fd, "0");
4543        break;
4544      case Ttime:
4545        { char tmp[256];
4546          time_t t = time(NULL), *p = &t;
4547          strftime(tmp, 256, "%Y-%m-%dT%H:%M:%SZ", gmtime(p));
4548	  fprintf(fd, "%s", tmp);
4549	}
4550	break;
4551      case Tpointer:
4552      case Treference:
4553	if (is_string(p) || is_wstring(p))
4554	{ if (p->minLength > 0 && p->minLength < 10000)
4555	    for (i = 0; i < p->minLength; i++)
4556	      fprintf(fd, "X");
4557	}
4558        else if (n < 10)
4559	  gen_val(fd, n, p->ref, nse, nsa, encoding);
4560	break;
4561      case Tclass:
4562      case Tstruct:
4563	if (!is_dynamic_array(p) && !is_primclass(p) && p->ref)
4564        { nse = ns_qualifiedElement(p);
4565  	  nsa = ns_qualifiedAttribute(p);
4566	  fprintf(fd, "\n");
4567	  for (q = ((Table*)p->ref)->list; q; q = q->next)
4568	    gen_field(fd, n+1, q, nse, nsa, encoding);
4569	  fprintf(fd, "%*s", n, "");
4570        }
4571        break;
4572      case Tunion:
4573        if (((Table*)p->ref)->list)
4574          gen_field(fd, n, ((Table*)p->ref)->list, nse, nsa, encoding);
4575	break;
4576      case Ttemplate:
4577        if (n < 10)
4578          gen_val(fd, n, p->ref, nse, nsa, encoding);
4579        break;
4580      default:
4581        break;
4582    }
4583  }
4584}
4585
4586void
4587gen_header(FILE *fd, char *method, int response, char *encoding)
4588{ if (custom_header)
4589  { Service *sp;
4590    Method *m = NULL;
4591    Entry *q;
4592    Table *r;
4593    fprintf(fd, " <SOAP-ENV:Header>\n");
4594    q = entry(classtable, lookup("SOAP_ENV__Header"));
4595    if (q)
4596    { r = q->info.typ->ref;
4597      if (r)
4598      { for (q = r->list; q; q = q->next)
4599        { if (!is_transient(q->info.typ) && !(q->info.sto & Sattribute) && q->info.typ->type != Tfun)
4600          { for (sp = services; sp; sp = sp->next)
4601              for (m = sp->list; m; m = m->next)
4602	        if (is_eq(m->name, method) && (!strcmp(m->part, q->sym->name) || is_eq_nons(m->part, q->sym->name)) && ((!response && (m->mess&HDRIN)) || (response && (m->mess&HDROUT))))
4603	        { gen_field(fd, 2, q, NULL, NULL, encoding);
4604	          break;
4605                }
4606          }
4607	}
4608        fprintf(fd, " </SOAP-ENV:Header>\n");
4609      }
4610    }
4611  }
4612}
4613
4614FILE *
4615gen_env(char *buf, char *method, int response, Table *t, char *ns, char *name, char *URL, char *executable, char *URI, char *encoding)
4616{ Symbol *s;
4617  Service *sp = NULL;
4618  char tmp[1024];
4619  FILE *fd;
4620  strcpy(tmp, buf);
4621  strcpy(strrchr(tmp, '.')+1, method);
4622  if (!response)
4623  { strcat(tmp, ".req.xml");
4624    fprintf(fmsg, "Saving %s sample SOAP/XML request\n", tmp);
4625  }
4626  else
4627  { strcat(tmp, ".res.xml");
4628    fprintf(fmsg, "Saving %s sample SOAP/XML response\n", tmp);
4629  }
4630  fd = fopen(tmp, "w");
4631  if (!fd)
4632    execerror("Cannot write XML file");
4633  fprintf(fd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
4634  fprintf(fd, "<SOAP-ENV:Envelope");
4635  for (s = nslist; s; s = s->next)
4636  { for (sp = services; sp; sp = sp->next)
4637      if (!tagcmp(sp->ns, s->name) && sp->URI)
4638        break;
4639    if (sp)
4640      fprintf(fd, "\n xmlns:%s=\"%s\"", ns_convert(s->name), sp->URI);
4641    else if (!strcmp(s->name, "SOAP-ENV"))
4642      fprintf(fd, "\n xmlns:SOAP-ENV=\"%s\"", envURI);
4643    else if (!strcmp(s->name, "SOAP-ENC"))
4644      fprintf(fd, "\n xmlns:SOAP-ENC=\"%s\"", encURI);
4645    else if (!strcmp(s->name, "xsi"))
4646      fprintf(fd, "\n xmlns:xsi=\"%s\"", xsiURI);
4647    else if (!strcmp(s->name, "xsd"))
4648      fprintf(fd, "\n xmlns:xsd=\"%s\"", xsdURI);
4649    else
4650      fprintf(fd, "\n xmlns:%s=\"%s/%s.xsd\"", ns_convert(s->name), tmpURI, ns_convert(s->name));
4651  }
4652  fprintf(fd, ">\n");
4653  gen_header(fd, method, response, encoding);
4654  fprintf(fd, " <SOAP-ENV:Body");
4655  if (eflag && !encoding)
4656    fprintf(fd, " SOAP-ENV:encodingStyle=\"%s\"", encURI);
4657  else if (encoding && !*encoding)
4658    fprintf(fd, " SOAP-ENV:encodingStyle=\"%s\"", encURI);
4659  else if (encoding && strcmp(encoding, "literal"))
4660    fprintf(fd, " SOAP-ENV:encodingStyle=\"%s\"", encoding);
4661  fprintf(fd, ">\n");
4662  return fd;
4663}
4664
4665char *
4666emalloc(size_t n)
4667{ char	*p;
4668  if ((p = (char*)malloc(n)) == NULL)
4669    execerror("out of memory");
4670  return p;
4671}
4672
4673void
4674soap_serve(Table *table)
4675{ Entry *method, *catch_method;
4676  if (!Cflag)
4677  {
4678  fprintf(fserver,"\n\nSOAP_FMAC5 int SOAP_FMAC6 %s_serve(struct soap *soap)", nflag?prefix:"soap");
4679
4680  fprintf(fserver,"\n{\n#ifndef WITH_FASTCGI\n\tunsigned int k = soap->max_keep_alive;\n#endif\n\n\tdo\n\t{");
4681  fprintf(fserver,"\n#ifdef WITH_FASTCGI\n\t\tif (FCGI_Accept() < 0)\n\t\t{\n\t\t\tsoap->error = SOAP_EOF;\n\t\t\treturn soap_send_fault(soap);\n\t\t}\n#endif");
4682  fprintf(fserver,"\n\n\t\tsoap_begin(soap);");
4683
4684  fprintf(fserver,"\n\n#ifndef WITH_FASTCGI\n\t\tif (soap->max_keep_alive > 0 && !--k)\n\t\t\tsoap->keep_alive = 0;\n#endif");
4685  fprintf(fserver,"\n\n\t\tif (soap_begin_recv(soap))\n\t\t{\tif (soap->error < SOAP_STOP)\n\t\t\t{\n#ifdef WITH_FASTCGI\n\t\t\t\tsoap_send_fault(soap);\n#else \n\t\t\t\treturn soap_send_fault(soap);\n#endif\n\t\t\t}\n\t\t\tsoap_closesock(soap);\n\n\t\t\tcontinue;\n\t\t}");
4686  fprintf(fserver,"\n\n\t\tif (soap_envelope_begin_in(soap)\n\t\t || soap_recv_header(soap)\n\t\t || soap_body_begin_in(soap)\n\t\t || %s_serve_request(soap)\n\t\t || (soap->fserveloop && soap->fserveloop(soap)))\n\t\t{\n#ifdef WITH_FASTCGI\n\t\t\tsoap_send_fault(soap);\n#else\n\t\t\treturn soap_send_fault(soap);\n#endif\n\t\t}", nflag?prefix:"soap");
4687  fprintf(fserver,"\n\n#ifdef WITH_FASTCGI\n\t\tsoap_destroy(soap);\n\t\tsoap_end(soap);\n\t} while (1);\n#else\n\t} while (soap->keep_alive);\n#endif");
4688
4689  fprintf(fserver,"\n\treturn SOAP_OK;");
4690  fprintf(fserver,"\n}");
4691
4692  fprintf(fserver,"\n\n#ifndef WITH_NOSERVEREQUEST\nSOAP_FMAC5 int SOAP_FMAC6 %s_serve_request(struct soap *soap)\n{", nflag?prefix:"soap");
4693  fprintf(fserver, "\n\tsoap_peek_element(soap);");
4694  catch_method = NULL;
4695  for (method = table->list; method; method = method->next)
4696  { char *action = NULL;
4697    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern))
4698    { if (aflag)
4699      { Service *sp;
4700        for (sp = services; sp; sp = sp->next)
4701        { if (has_ns_eq(sp->ns, method->sym->name))
4702	  { Method *m;
4703	    for (m = sp->list; m; m = m->next)
4704	    { if (is_eq_nons(m->name, method->sym->name))
4705	      { if (m->mess == ACTION)
4706	          action = m->part;
4707	      }
4708	    }
4709  	  }
4710        }
4711      }
4712      if (is_invisible(method->sym->name))
4713      { Entry *param = entry(classtable, method->sym);
4714	if (param)
4715	{ param = ((Table*)param->info.typ->ref)->list;
4716	  if (param)
4717	  { if (action)
4718              if (*action == '"')
4719	        fprintf(fserver, "\n\tif ((!soap->action && !soap_match_tag(soap, soap->tag, \"%s\")) || (soap->action && !strcmp(soap->action, %s))", ns_convert(param->sym->name), action);
4720              else
4721	        fprintf(fserver, "\n\tif ((!soap->action && !soap_match_tag(soap, soap->tag, \"%s\")) || (soap->action && !strcmp(soap->action, \"%s\"))", ns_convert(param->sym->name), action);
4722	    else
4723              fprintf(fserver,"\n\tif (!soap_match_tag(soap, soap->tag, \"%s\")", ns_convert(param->sym->name));
4724            fprintf(fserver, ")\n\t\treturn soap_serve_%s(soap);", ident(method->sym->name));
4725	  }
4726	  else
4727	    catch_method = method;
4728	}
4729      }
4730      else
4731      { if (action)
4732          if (*action == '"')
4733	    fprintf(fserver, "\n\tif ((!soap->action && !soap_match_tag(soap, soap->tag, \"%s\")) || (soap->action && !strcmp(soap->action, %s))", ns_convert(method->sym->name), action);
4734          else
4735	    fprintf(fserver, "\n\tif ((!soap->action && !soap_match_tag(soap, soap->tag, \"%s\")) || (soap->action && !strcmp(soap->action, \"%s\"))", ns_convert(method->sym->name), action);
4736	else
4737          fprintf(fserver,"\n\tif (!soap_match_tag(soap, soap->tag, \"%s\")", ns_convert(method->sym->name));
4738        fprintf(fserver, ")\n\t\treturn soap_serve_%s(soap);", ident(method->sym->name));
4739      }
4740    }
4741  }
4742  if (catch_method)
4743    fprintf(fserver, "\n\treturn soap_serve_%s(soap);", ident(catch_method->sym->name));
4744  else
4745    fprintf(fserver,"\n\treturn soap->error = SOAP_NO_METHOD;");
4746
4747  fprintf(fserver,"\n}\n#endif");
4748
4749  banner(fheader, "Service Operations");
4750  for (method = table->list; method; method = method->next)
4751    if (method->info.typ->type == Tfun && !(method->info.sto & Sextern))
4752	generate_proto(table, method);
4753  }
4754
4755  if (!Sflag)
4756  { banner(fheader, "Stubs");
4757    for (method = table->list; method; method = method->next)
4758      if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && !is_imported(method->info.typ))
4759	gen_call_method(fclient, table, method, NULL);
4760  }
4761
4762  if (!Cflag)
4763  { banner(fheader, "Skeletons");
4764    fprintf(fheader, "\nSOAP_FMAC5 int SOAP_FMAC6 %s_serve(struct soap*);", nflag?prefix:"soap");
4765    fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 %s_serve_request(struct soap*);", nflag?prefix:"soap");
4766    for (method = table->list; method; method = method->next)
4767      if (method->info.typ->type == Tfun && !(method->info.sto & Sextern) && !is_imported(method->info.typ))
4768	gen_serve_method(fserver, table, method, NULL);
4769  }
4770}
4771
4772void
4773generate_proto(Table *table, Entry *param)
4774{ Entry *q,*pout;
4775  Table *output;
4776  q=entry(table, param->sym);
4777  if (q)
4778    pout = (Entry*)q->info.typ->ref;
4779  else
4780  { fprintf(stderr, "Internal error: no table entry\n");
4781    return;
4782  }
4783  q=entry(classtable, param->sym);
4784  output=(Table*) q->info.typ->ref;
4785  fprintf(fheader, "\n\nSOAP_FMAC5 int SOAP_FMAC6 %s(struct soap*", ident(param->sym->name));
4786  gen_params(fheader, output, pout, 1);
4787  fprintf(fheader,";");
4788}
4789
4790int
4791tagcmp(const char *s, const char *t)
4792{ size_t i, n;
4793  n = strlen(s);
4794  for (i = 0; i < n; i++)
4795  { int c = t[i];
4796    if (c == '_')
4797      c = '-';
4798    if (s[i] > c)
4799      return 1;
4800    if (s[i] < c)
4801      return -1;
4802  }
4803  return -(t[i] != 0);
4804}
4805
4806int
4807is_qname(Tnode *p)
4808{ return p->sym && is_string(p) && (is_eq(p->sym->name, "xsd__QName") || is_eq(p->sym->name, "QName"));
4809}
4810
4811int
4812is_stdqname(Tnode *p)
4813{ return p->sym && is_stdstring(p) && (is_eq(p->sym->name, "xsd__QName") || is_eq(p->sym->name, "QName"));
4814}
4815
4816int
4817is_XML(Tnode *p)
4818{ return (p->sym && (is_string(p) || is_wstring(p)) && is_eq(p->sym->name, "XML")) || ((p->type == Tpointer || p->type == Treference) && is_XML(p->ref));
4819}
4820
4821int
4822is_response(Tnode *p)
4823{ return (p->type == Tpointer || p->type == Treference) && p->ref && ((((Tnode*)p->ref)->type == Tstruct || ((Tnode*)p->ref)->type == Tclass) && !is_primclass(p->ref) && !is_dynamic_array(p->ref) && !is_stdstring(p->ref) && !is_stdwstring(p->ref));
4824}
4825
4826Entry*
4827get_response(Tnode *p)
4828{ if (p->type == Tfun)
4829    return p->response;
4830  return 0;
4831}
4832
4833int
4834is_unmatched(Symbol *sym)
4835{ return sym->name[0] == '_'
4836      && sym->name[1] != '_'
4837      && strncmp(sym->name, "_DOT", 4)
4838      && strncmp(sym->name, "_USCORE", 7)
4839      && (strncmp(sym->name, "_x", 2) || !isxdigit(sym->name[2]) || !isxdigit(sym->name[3]) || !isxdigit(sym->name[4]) || !isxdigit(sym->name[5]));
4840}
4841
4842int
4843is_invisible(const char *name)
4844{ return name[0] == '-' || (name[0] == '_' && name[1] == '_' && strncmp(name, "__ptr", 5));
4845}
4846
4847int
4848is_element(Tnode *typ)
4849{ if (typ->sym)
4850    return is_unmatched(typ->sym);
4851  if (typ->type == Tstruct || typ->type == Tclass)
4852    return is_unmatched(typ->id);
4853  return 0;
4854}
4855
4856int
4857is_untyped(Tnode *typ)
4858{ Tnode *p;
4859  if (typ->sym)
4860    return is_unmatched(typ->sym);
4861  if (typ->type == Tpointer || typ->type == Treference || typ->type == Tarray)
4862    return is_untyped(typ->ref);
4863  if (typ->type == Tstruct || typ->type == Tclass)
4864  { if (is_dynamic_array(typ) && !has_ns(typ) && !is_binary(typ))
4865    { p = ((Table*)typ->ref)->list->info.typ->ref;
4866        return is_untyped(p);
4867    }
4868    else
4869      return is_unmatched(typ->id);
4870  }
4871  return 0;
4872}
4873
4874int
4875is_primclass(Tnode *typ)
4876{ Table *t;
4877  if (typ->type == Tstruct || typ->type == Tclass)
4878  { if (!is_dynamic_array(typ))
4879    { t = (Table*)typ->ref;
4880      while (t)
4881      { if (t->list && is_item(t->list))
4882          break;
4883	t = t->prev;
4884      }
4885      if (!t)
4886        return 0;
4887      t = (Table*)typ->ref;
4888      while (t)
4889      { Entry *p;
4890        for (p = t->list; p; p = p->next)
4891	  if (!is_item(p))
4892	    if (p->info.typ->type != Tfun && !is_transient(p->info.typ) && p->info.sto != Sattribute && p->info.sto != Sprivate && p->info.sto != Sprotected)
4893	      return 0;
4894        t = t->prev;
4895      }
4896      return 1;
4897    }
4898  }
4899  else if (typ->type == Tpointer || typ->type == Treference)
4900    return is_primclass(typ->ref);
4901  return 0;
4902}
4903
4904int
4905is_mask(Tnode *typ)
4906{ return (typ->type == Tenum && typ->width == 8);
4907}
4908
4909int
4910is_void(Tnode *typ)
4911{ if (!typ)
4912    return 1;
4913  if (typ->type == Tvoid)
4914    return 1;
4915  if (typ->type == Tpointer)
4916    return is_void(typ->ref);
4917  if (typ->type == Treference)
4918    return is_void(typ->ref);
4919  if (typ->type == Tarray)
4920    return is_void(typ->ref);
4921  if (typ->type == Ttemplate)
4922    return is_void(typ->ref);
4923  return 0;
4924}
4925
4926int
4927is_transient(Tnode *typ)
4928{ if (!typ)
4929    return 1;
4930  if (typ->type == Tstruct && typ->id == lookup("soap"))
4931    return 1;
4932  if (is_external(typ) || is_volatile(typ))
4933    return 0;
4934  if (typ->transient)
4935    return 1;
4936  switch (typ->type)
4937  { case Tpointer:
4938    case Treference:
4939    case Tarray:
4940    case Ttemplate:
4941      return is_transient(typ->ref);
4942    case Tnone:
4943    case Tvoid:
4944      return 1;
4945    default:
4946      break;
4947  }
4948  return 0;
4949}
4950
4951int
4952is_imported(Tnode* typ)
4953{ return typ->imported != NULL;
4954}
4955
4956int
4957is_external(Tnode* typ)
4958{ return typ->transient == -1;
4959}
4960
4961int
4962is_anyType(Tnode* typ)
4963{ if (typ->type == Tpointer)
4964    return is_anyType(typ->ref);
4965  return is_external(typ) && typ->type == Tstruct && !strcmp(typ->id->name, "soap_dom_element");
4966}
4967
4968int
4969is_anyAttribute(Tnode* typ)
4970{ if (typ->type == Tpointer)
4971    return is_anyAttribute(typ->ref);
4972  return is_external(typ) && typ->type == Tstruct && !strcmp(typ->id->name, "soap_dom_attribute");
4973}
4974
4975int
4976is_volatile(Tnode* typ)
4977{ return typ->transient == -2;
4978}
4979
4980int
4981is_template(Tnode *p)
4982{ if (p->type == Tpointer)
4983    return is_template(p->ref);
4984  return p->type == Ttemplate;
4985}
4986
4987int
4988is_repetition(Entry *p)
4989{ if (p)
4990    return p->next && p->next->info.typ->type == Tpointer && (p->info.typ->type == Tint || p->info.typ->type == Tuint) && !strncmp(p->sym->name, "__size", 6);
4991  return 0;
4992}
4993
4994int
4995is_item(Entry *p)
4996{ if (p)
4997    return !strcmp(p->sym->name, "__item");
4998  return 0;
4999}
5000
5001int
5002is_choice(Entry *p)
5003{ if (p)
5004    if (p->next && p->next->info.typ->type == Tunion && p->info.typ->type == Tint && !strncmp(p->sym->name, "__union", 7))
5005      return 1;
5006  return 0;
5007}
5008
5009int
5010is_sequence(Entry *p)
5011{ if (p)
5012  { Tnode *q = p->info.typ;
5013    if (q->type == Tpointer)
5014      q = q->ref;
5015    if (q->type == Tstruct && is_invisible(p->sym->name) && is_invisible(q->id->name) && !is_transient(q))
5016      return 1;
5017  }
5018  return 0;
5019}
5020
5021
5022int
5023is_anytype(Entry *p)
5024{ if (p)
5025    if (p->next && p->next->info.typ->type == Tpointer && ((Tnode*)p->next->info.typ->ref)->type == Tvoid && p->info.typ->type == Tint && !strncmp(p->sym->name, "__type", 6))
5026    { is_anytype_flag = 1;
5027      return 1;
5028    }
5029  return 0;
5030}
5031
5032int
5033is_keyword(const char *name)
5034{ Symbol *s = lookup(name);
5035  if (s)
5036    return s->token != ID;
5037  return 0;
5038}
5039
5040
5041int
5042has_ptr(Tnode *typ)
5043{ Tnode	*p;
5044  if (typ->type == Tpointer || typ->type == Treference)
5045    return 0;
5046  for (p = Tptr[Tpointer]; p; p = p->next)
5047    if (p->ref == typ && p->transient != 1)
5048      return 1;
5049  return 0;
5050}
5051
5052int
5053has_detail_string()
5054{ Entry *p = entry(classtable, lookup("SOAP_ENV__Fault"));
5055  if (p && p->info.typ->ref && (p->info.typ->type == Tstruct || p->info.typ->type == Tclass))
5056  { Entry *e = entry(p->info.typ->ref, lookup("detail"));
5057    if (e && e->info.typ->ref && e->info.typ->type == Tpointer && ((Tnode*)e->info.typ->ref)->type == Tstruct)
5058    { Entry *e2 = entry(((Tnode*)e->info.typ->ref)->ref, lookup("__any"));
5059      return e2 && is_string(e2->info.typ);
5060    }
5061  }
5062  return 0;
5063}
5064
5065int
5066has_Detail_string()
5067{ Entry *p = entry(classtable, lookup("SOAP_ENV__Fault"));
5068  if (p && p->info.typ->ref && (p->info.typ->type == Tstruct || p->info.typ->type == Tclass))
5069  { Entry *e = entry(p->info.typ->ref, lookup("SOAP_ENV__Detail"));
5070    if (e && e->info.typ->ref && e->info.typ->type == Tpointer && ((Tnode*)e->info.typ->ref)->type == Tstruct)
5071    { Entry *e2 = entry(((Tnode*)e->info.typ->ref)->ref, lookup("__any"));
5072      return e2 && is_string(e2->info.typ);
5073    }
5074  }
5075  return 0;
5076}
5077
5078int
5079has_class(Tnode *typ)
5080{ Entry *p;
5081  if (typ->type == Tstruct && typ->ref)
5082  { for (p = ((Table*)typ->ref)->list; p; p = p->next)
5083    { if (p->info.sto & Stypedef)
5084        continue;
5085      if (p->info.typ->type == Tclass || p->info.typ->type == Ttemplate)
5086        return 1;
5087      if (p->info.typ->type == Tstruct && has_class(p->info.typ))
5088        return 1;
5089    }
5090  }
5091  return 0;
5092}
5093
5094int
5095has_external(Tnode *typ)
5096{ Entry *p;
5097  if ((typ->type == Tstruct || typ->type == Tclass) && typ->ref)
5098  { for (p = ((Table*)typ->ref)->list; p; p = p->next)
5099    { if (p->info.typ->type == Tstruct || p->info.typ->type == Tclass)
5100      { if (is_external(p->info.typ) || has_external(p->info.typ))
5101          return 1;
5102      }
5103    }
5104  }
5105  return 0;
5106}
5107
5108int
5109has_volatile(Tnode *typ)
5110{ Entry *p;
5111  if ((typ->type == Tstruct || typ->type == Tclass) && typ->ref)
5112  { for (p = ((Table*)typ->ref)->list; p; p = p->next)
5113    { if (p->info.typ->type == Tstruct || p->info.typ->type == Tclass)
5114      { if (is_volatile(p->info.typ) || has_volatile(p->info.typ))
5115	  if (!is_stdstr(p->info.typ))
5116            return 1;
5117      }
5118    }
5119  }
5120  return 0;
5121}
5122
5123int
5124has_ns(Tnode *typ)
5125{ if (typ->type == Tstruct || typ->type == Tclass || typ->type == Tenum)
5126    return has_ns_eq(NULL, typ->id->name);
5127  return 0;
5128}
5129
5130int
5131has_ns_t(Tnode *typ)
5132{ char *s;
5133  if (typ->sym)
5134  { s = strstr(typ->sym->name + 1, "__");
5135    if (!s)
5136    { s = strchr(typ->sym->name, ':');
5137      if (s && s[1] == ':')
5138        s = NULL;
5139    }
5140    return s && s[1] && s[2] && s[2] != '_';
5141  }
5142  return has_ns(typ);
5143}
5144
5145/* needs_lang adds xml:lang attribute to matching struct/class member name
5146   we should use an annotation for soapcpp2's input this in the future instead
5147   of a hard-coded member name */
5148void
5149needs_lang(Entry *e)
5150{ if (!strcmp(e->sym->name, "SOAP_ENV__Text"))
5151    fprintf(fout, "\n\tif (soap->lang)\n\t\tsoap_set_attr(soap, \"xml:lang\", soap->lang);");
5152}
5153
5154int
5155is_eq_nons(const char *s, const char *t)
5156{ size_t n, m;
5157  char *r;
5158  while (*s == '_')
5159    s++;
5160  while (*t == '_')
5161    t++;
5162  if (!*s || !*t)
5163    return 0;
5164  r = strstr(t, "__");
5165  if (r)
5166    t = r + 2;
5167  for (n = strlen(s) - 1; n && s[n] == '_'; n--)
5168    ;
5169  for (m = strlen(t) - 1; m && t[m] == '_'; m--)
5170    ;
5171  if (n != m)
5172    return 0;
5173  return !strncmp(s, t, n + 1);
5174}
5175
5176int
5177is_eq(const char *s, const char *t)
5178{ size_t n, m;
5179  while (*s == '_')
5180    s++;
5181  while (*t == '_')
5182    t++;
5183  if (!*s || !*t)
5184    return 0;
5185  for (n = strlen(s) - 1; n && s[n] == '_'; n--)
5186    ;
5187  for (m = strlen(t) - 1; m && t[m] == '_'; m--)
5188    ;
5189  if (n != m)
5190    return 0;
5191  return !strncmp(s, t, n + 1);
5192}
5193
5194int
5195has_ns_eq(char *ns, char *s)
5196{ size_t n;
5197  while (*s == '_')
5198    s++;
5199  if (!ns)
5200  { char *t = strstr(s + 1, "__");
5201    if (!t)
5202    { t = strchr(s, ':');
5203      if (t && t[1] == ':')
5204        t = NULL;
5205    }
5206    return t && t[1] && t[2] && t[2] != '_';
5207  }
5208  if ((n = strlen(ns)) < strlen(s))
5209    return s[n] == '_' && s[n+1] == '_' && !strncmp(ns, s, n);
5210  return 0;
5211}
5212
5213char *
5214strict_check()
5215{ if (sflag)
5216    return "";
5217  return "(soap->mode & SOAP_XML_STRICT) && ";
5218}
5219
5220char *
5221ns_of(char *name)
5222{ Service *sp;
5223  for (sp = services; sp; sp = sp->next)
5224    if (has_ns_eq(sp->ns, name))
5225      break;
5226  if (sp)
5227    return sp->URI;
5228  return NULL;
5229}
5230
5231char *
5232prefix_of(char *s)
5233{ char *t;
5234  while (*s == '_')
5235    s++;
5236  t = strstr(s + 1, "__");
5237  if (!t)
5238  { t = strchr(s, ':');
5239    if (t && t[1] == ':')
5240      t = NULL;
5241  }
5242  if (t && t[1] && t[2] && t[2] != '_')
5243  { char *r  = (char*)emalloc(t - s + 1);
5244    strncpy(r, s, t - s);
5245    r[t - s] = '\0';
5246    return r;
5247  }
5248  return s;
5249}
5250
5251char *
5252ns_add_overridden(Table *t, Entry *p, char *ns)
5253{ Entry *q;
5254  Symbol *s = t->sym;
5255  if (s)
5256    do
5257    { for (q = t->list; q; q = q->next)
5258        if (!strcmp(q->sym->name, p->sym->name))
5259	  return ns_add(p->sym->name, ns ? prefix_of(t->sym->name) : NULL);
5260    } while ((t = t->prev) != NULL);
5261  return ns_add(p->sym->name, ns);
5262}
5263
5264
5265char *
5266c_ident(Tnode *typ)
5267{ if (typ->sym && strcmp(typ->sym->name, "/*?*/"))
5268    return res_remove(typ->sym->name);
5269  return t_ident(typ);
5270}
5271
5272char *
5273soap_type(Tnode *typ)
5274{ char *s, *t = c_ident(typ);
5275  if (namespaceid)
5276  { s = (char*)emalloc(strlen(t) + strlen(namespaceid) + 12);
5277    strcpy(s, "SOAP_TYPE_");
5278    strcat(s, namespaceid);
5279    strcat(s, "_");
5280  }
5281  else
5282  { s = (char*)emalloc(strlen(t) + 11);
5283    strcpy(s, "SOAP_TYPE_");
5284  }
5285  strcat(s, t);
5286  return s;
5287}
5288
5289char *
5290ident(char *name)
5291{ char *s = strrchr(name, ':');
5292  if (s && *(s+1) && *(s-1) != ':')
5293    return s+1;
5294  return name;
5295}
5296
5297/*t_ident gives the name of a type in identifier format*/
5298char *
5299t_ident(Tnode *typ)
5300{ char *p, *q;
5301  switch(typ->type)
5302  {
5303  case Tnone:
5304    return "";
5305  case Tvoid:
5306    return "void";
5307  case Tchar:
5308    return "byte";
5309  case Twchar:
5310    return "wchar";
5311  case Tshort:
5312    return "short";
5313  case Tint:
5314    return "int";
5315  case Tlong:
5316    return "long";
5317  case Tllong:
5318    return "LONG64";
5319  case Tfloat:
5320    return "float";
5321  case Tdouble:
5322    return "double";
5323  case Tldouble:
5324    return "decimal";
5325  case Tuchar:
5326    return "unsignedByte";
5327  case Tushort:
5328    return "unsignedShort";
5329  case Tuint:
5330    return "unsignedInt";
5331  case Tulong:
5332    return "unsignedLong";
5333  case Tullong:
5334    return "unsignedLONG64";
5335  case Ttime:
5336    return "time";
5337  case Tstruct:
5338  case Tclass:
5339  case Tunion:
5340  case Tenum:
5341    if (typ->ref == booltable)
5342      return "bool";
5343    return res_remove(typ->id->name);
5344  case Treference:
5345    return c_ident(typ->ref);
5346  case Tpointer:
5347    if (is_string(typ))
5348	return "string";
5349    if (is_wstring(typ))
5350	return "wstring";
5351    p=(char*) emalloc((10+strlen(q = c_ident(typ->ref)))*sizeof(char));
5352    strcpy(p,"PointerTo");
5353    strcat(p,q);
5354    return p;
5355  case Tarray:
5356    p=(char*) emalloc((16+strlen(c_ident(typ->ref)))*sizeof(char));
5357    if (((Tnode*)typ->ref)->width)
5358      sprintf(p, "Array%dOf%s",typ->width / ((Tnode*) typ->ref)->width,c_ident(typ->ref));
5359    else
5360      sprintf(p, "ArrayOf%s", c_ident(typ->ref));
5361    return p;
5362  case Ttemplate:
5363    if (typ->ref)
5364    { p=(char*) emalloc((11+strlen(res_remove(typ->id->name))+strlen(q = c_ident(typ->ref)))*sizeof(char));
5365      strcpy(p, res_remove(typ->id->name));
5366      strcat(p, "TemplateOf");
5367      strcat(p, q);
5368      return p;
5369    }
5370  case Tfun:
5371    return "Function";
5372  }
5373  return "anyType";
5374}
5375
5376void
5377utf8(char **t, long c)
5378{ if (c < 0x0080)
5379    *(*t)++ = (char)c;
5380  else
5381  { if (c < 0x0800)
5382      *(*t)++ = (char)(0xC0 | ((c >> 6) & 0x1F));
5383    else
5384    { if (c < 0x010000)
5385        *(*t)++ = (char)(0xE0 | ((c >> 12) & 0x0F));
5386      else
5387      { if (c < 0x200000)
5388          *(*t)++ = (char)(0xF0 | ((c >> 18) & 0x07));
5389        else
5390        { if (c < 0x04000000)
5391            *(*t)++ = (char)(0xF8 | ((c >> 24) & 0x03));
5392          else
5393          { *(*t)++ = (char)(0xFC | ((c >> 30) & 0x01));
5394            *(*t)++ = (char)(0x80 | ((c >> 24) & 0x3F));
5395          }
5396          *(*t)++ = (char)(0x80 | ((c >> 18) & 0x3F));
5397        }
5398        *(*t)++ = (char)(0x80 | ((c >> 12) & 0x3F));
5399      }
5400      *(*t)++ = (char)(0x80 | ((c >> 6) & 0x3F));
5401    }
5402    *(*t)++ = (char)(0x80 | (c & 0x3F));
5403  }
5404  *(*t) = '\0';
5405}
5406
5407char *
5408ns_convert(char *tag)
5409{ char *t, *s;
5410  size_t i, n;
5411  if (*tag == '_')
5412  { if (!strncmp(tag, "__ptr", 5))
5413      if (tag[5])
5414        tag += 5;
5415      else
5416        tag = "item";
5417    else if (strncmp(tag, "_DOT", 4)
5418          && strncmp(tag, "_USCORE", 7)
5419          && (strncmp(tag, "_x", 2) || !isxdigit(tag[2]) || !isxdigit(tag[3]) || !isxdigit(tag[4]) || !isxdigit(tag[5])))
5420      tag++; /* skip leading _ */
5421  }
5422  for (n = strlen(tag); n > 0; n--)
5423    if (tag[n-1] != '_')
5424      break;
5425  s = t = (char*)emalloc(n+1);
5426  for (i = 0; i < n; i++)
5427  { if (tag[i] == '_')
5428      if (tag[i+1] == '_')
5429        break;
5430      else if (!strncmp(tag+i, "_DOT", 4))
5431      { *s++ = '.';
5432        i += 3;
5433      }
5434      else if (!strncmp(tag+i, "_USCORE", 7))
5435      { *s++ = '_';
5436        i += 6;
5437      }
5438      else if (!strncmp(tag+i, "_x", 2) && isxdigit(tag[i+2]) && isxdigit(tag[i+3]) && isxdigit(tag[i+4]) && isxdigit(tag[i+5]))
5439      { char d[5];
5440	strncpy(d, tag+i+2, 4);
5441	d[4] = '\0';
5442        utf8(&s, strtoul(d, NULL, 16));
5443        i += 5;
5444      }
5445      else
5446        *s++ = '-';
5447    else if (tag[i] == ':' && tag[i+1] == ':')
5448      break;
5449    else
5450      *s++ = tag[i];
5451  }
5452  if (i < n)
5453  { *s++ = ':';
5454    for (i += 2; i < n; i++)
5455      if (tag[i] == '_')
5456        if (!strncmp(tag+i, "_DOT", 4))
5457        { *s++ = '.';
5458          i += 3;
5459        }
5460        else if (!strncmp(tag+i, "_USCORE", 7))
5461        { *s++ = '_';
5462          i += 6;
5463        }
5464        else if (!strncmp(tag+i, "_x", 2) && isxdigit(tag[i+2]) && isxdigit(tag[i+3]) && isxdigit(tag[i+4]) && isxdigit(tag[i+5]))
5465        { char d[5];
5466	  strncpy(d, tag+i+2, 4);
5467	  d[4] = '\0';
5468          utf8(&s, strtoul(d, NULL, 16));
5469          i += 5;
5470        }
5471	else
5472	  *s++ = '-';
5473      else
5474        *s++ = tag[i];
5475  }
5476  *s = '\0';
5477  return t;
5478}
5479
5480char *
5481res_remove(char *tag)
5482{ char *s, *t;
5483  if (!(s = strchr(tag, ':')))
5484    return tag;
5485  s = emalloc(strlen(tag) + 1);
5486  strcpy(s, tag);
5487  while ((t = strchr(s, ':')))
5488    *t = '_';
5489  return s;
5490}
5491
5492char *
5493ns_qualifiedElement(Tnode *typ)
5494{ Service *sp;
5495  char *s = NULL;
5496  if (typ->sym)
5497    s = prefix_of(typ->sym->name);
5498  if (!s && typ->id)
5499    s = prefix_of(typ->id->name);
5500  if (!s)
5501    return NULL;
5502  for (sp = services; sp; sp = sp->next)
5503  { if (sp->elementForm && !tagcmp(sp->ns, s))
5504    { if (!strcmp(sp->elementForm, "qualified"))
5505        return s;
5506      return NULL;
5507    }
5508  }
5509  for (sp = services; sp; sp = sp->next)
5510    if (!tagcmp(sp->ns, s))
5511      if (sp->style && !strcmp(sp->style, "document"))
5512        return s;
5513  return NULL;
5514}
5515
5516char *
5517ns_qualifiedAttribute(Tnode *typ)
5518{ Service *sp;
5519  char *s = NULL;
5520  if (typ->sym)
5521    s = prefix_of(typ->sym->name);
5522  if (!s && typ->id)
5523    s = prefix_of(typ->id->name);
5524  if (!s)
5525    return NULL;
5526  for (sp = services; sp; sp = sp->next)
5527  { if (sp->attributeForm && !tagcmp(sp->ns, s))
5528    { if (!strcmp(sp->attributeForm, "qualified"))
5529        return s;
5530      return NULL;
5531    }
5532  }
5533  return NULL;
5534}
5535
5536char *
5537ns_add(char *tag, char *ns)
5538{ char *n, *t, *s = ns_convert(tag);
5539  if (!ns || *s == '-' || (t = strchr(s, ':')))
5540    return s;
5541  n = ns_convert(ns);
5542  t = emalloc(strlen(n) + strlen(s) + 2);
5543  strcpy(t, n);
5544  strcat(t, ":");
5545  strcat(t, s);
5546  return t;
5547}
5548
5549char *
5550ns_name(char *tag)
5551{ char *t, *s = tag;
5552  if (*s)
5553    for (t = s + 1; *t; t++)
5554      if (t[0] == '_' && t[1] == '_')
5555      { s = t + 2;
5556        t++;
5557      }
5558  return s;
5559}
5560
5561char *
5562ns_cname(char *tag, char *suffix)
5563{ char *s, *t;
5564  size_t i, n;
5565  if (!tag)
5566    return NULL;
5567  t = ns_name(tag);
5568  n = strlen(t);
5569  if (suffix)
5570    s = emalloc(n + strlen(suffix) + 2);
5571  else
5572    s = emalloc(n + 2);
5573  for (i = 0; i < n; i++)
5574  { if (!isalnum(t[i]))
5575      s[i] = '_';
5576    else
5577      s[i] = t[i];
5578  }
5579  s[i] = '\0';
5580  if (suffix)
5581    strcat(s, suffix);
5582  if (is_keyword(t))
5583    strcat(s, "_");
5584  return s;
5585}
5586
5587char *
5588ns_remove(char *tag)
5589{ return ns_convert(ns_name(tag));
5590}
5591
5592char *
5593ns_remove1(char *tag)
5594{ char *t, *s = tag;
5595  int n = 2;
5596  /* handle 'enum_xx__yy' generated by wsdl2h
5597  if (!strncmp(s, "enum_", 5))
5598    n = 1;
5599  */
5600  if (*s)
5601  { for (t = s + 1; *t && n; t++)
5602      if (t[0] == '_' && t[1] == '_')
5603      { s = t + 2;
5604        t++;
5605	n--;
5606      }
5607    if (n || (s[0] == '_' && s[1] != 'x') || !*s)
5608      s = tag;
5609  }
5610  return s;
5611}
5612
5613char *
5614ns_remove2(char *tag)
5615{ return ns_convert(ns_remove1(tag));
5616}
5617
5618char *
5619xsi_type_cond(Tnode *typ, int flag)
5620{ if (flag)
5621    return xsi_type(typ);
5622  return "";
5623}
5624
5625char *
5626xsi_type_cond_u(Tnode *typ, int flag)
5627{ if (flag && tflag)
5628    return xsi_type(typ);
5629  return "";
5630}
5631
5632char *
5633xsi_type_u(Tnode *typ)
5634{ if (tflag)
5635    return xsi_type(typ);
5636  return "";
5637}
5638
5639char *
5640xsi_type(Tnode *typ)
5641{ if (!typ)
5642    return "NULL";
5643  if (is_dynamic_array(typ) && !has_ns(typ))
5644    return xsi_type_Darray(typ);
5645  if (typ->type == Tarray)
5646    return xsi_type_Tarray(typ);
5647  if (is_untyped(typ))
5648    return "";
5649  if (typ->sym)
5650  { if (!strncmp(typ->sym->name, "SOAP_ENV__", 10))
5651      return "";
5652    if (is_XML(typ))
5653      return "xsd:anyType";
5654    if (typ->type != Ttemplate)
5655      return ns_convert(typ->sym->name);
5656  }
5657  if (is_string(typ) || is_wstring(typ) || is_stdstring(typ) || is_stdwstring(typ))
5658    return "xsd:string";
5659  switch(typ->type){
5660  case Tchar:
5661    return "xsd:byte";
5662  case Twchar:
5663    return "wchar";
5664  case Tshort:
5665    return "xsd:short";
5666  case Tint:
5667    return "xsd:int";
5668  case Tlong:
5669  case Tllong:
5670    return "xsd:long";
5671  case Tfloat:
5672    return "xsd:float";
5673  case Tdouble:
5674    return "xsd:double";
5675  case Tldouble:
5676    return "xsd:decimal";
5677  case Tuchar:
5678    return "xsd:unsignedByte";
5679  case Tushort:
5680    return "xsd:unsignedShort";
5681  case Tuint:
5682    return "xsd:unsignedInt";
5683  case Tulong:
5684  case Tullong:
5685    return "xsd:unsignedLong";
5686  case Ttime:
5687    return "xsd:dateTime";
5688  case Tpointer:
5689  case Treference:
5690    return xsi_type(typ->ref);
5691  case Tenum:
5692    if (typ->ref == booltable)
5693      return "xsd:boolean";
5694  case Tstruct:
5695  case Tclass:
5696    if (!strncmp(typ->id->name, "SOAP_ENV__", 10))
5697      return "";
5698    return ns_convert(typ->id->name);
5699  case Ttemplate:
5700    if (typ->ref)
5701      return xsi_type(typ->ref);
5702    break;
5703  default:
5704    break;
5705  }
5706  return "";
5707}
5708
5709char *
5710xml_tag(Tnode *typ)
5711{ if (!typ)
5712    return "NULL";
5713  if (typ->type == Tpointer || typ->type == Treference)
5714    return xml_tag(typ->ref);
5715  if (typ->sym)
5716    return ns_convert(typ->sym->name);
5717  return the_type(typ);
5718}
5719
5720char *
5721wsdl_type(Tnode *typ, char *ns)
5722{ if (!typ)
5723    return "NULL";
5724  if ((is_qname(typ) || is_stdqname(typ)) && ns)
5725      return "xsd:QName";
5726  if (typ->sym)
5727  { if (is_XML(typ))
5728      return "xsd:anyType";
5729    else if (ns)
5730      return ns_convert(typ->sym->name);
5731    else
5732      return ns_remove(typ->sym->name);
5733  }
5734  return base_type(typ, ns);
5735}
5736
5737char *
5738base_type(Tnode *typ, char *ns)
5739{ int d;
5740  char *s, *t;
5741  if (is_string(typ) || is_wstring(typ) || is_stdstring(typ) || is_stdwstring(typ))
5742  { if (ns)
5743      return "xsd:string";
5744    return "string";
5745  }
5746  if (is_dynamic_array(typ) && !is_binary(typ) && !has_ns(typ) && !is_untyped(typ))
5747  { s = ns_remove(wsdl_type(((Table*)typ->ref)->list->info.typ, NULL));
5748    if (ns && *ns)
5749    { t = (char*)emalloc(strlen(s)+strlen(ns_convert(ns))+13);
5750      strcpy(t, ns_convert(ns));
5751      strcat(t, ":");
5752      strcat(t, "ArrayOf");
5753    }
5754    else
5755    { t = (char*)emalloc(strlen(s)+12);
5756      strcpy(t, "ArrayOf");
5757    }
5758    strcat(t, s);
5759    d = get_Darraydims(typ);
5760    if (d)
5761      sprintf(t+strlen(t), "%dD", d);
5762    return t;
5763  }
5764  switch (typ->type){
5765  case Tchar :
5766    if (ns)
5767      return "xsd:byte";
5768    return "byte";
5769  case Twchar :
5770    if (ns)
5771      return "xsd:wchar";
5772    return "wchar";
5773  case Tshort :
5774    if (ns)
5775      return "xsd:short";
5776    return "short";
5777  case Tint  :
5778    if (ns)
5779      return "xsd:int";
5780    return "int";
5781  case Tlong  :
5782  case Tllong  :
5783    if (ns)
5784      return "xsd:long";
5785    return "long";
5786  case Tfloat:
5787    if (ns)
5788      return "xsd:float";
5789    return "float";
5790  case Tdouble:
5791    if (ns)
5792      return "xsd:double";
5793    return "double";
5794  case Tldouble:
5795    if (ns)
5796      return "xsd:decimal";
5797    return "decimal";
5798  case Tuchar:
5799    if (ns)
5800      return "xsd:unsignedByte";
5801    return "unsignedByte";
5802  case Tushort:
5803    if (ns)
5804      return "xsd:unsignedShort";
5805    return "unsignedShort";
5806  case Tuint:
5807    if (ns)
5808      return "xsd:unsignedInt";
5809    return "unsignedInt";
5810  case Tulong:
5811  case Tullong:
5812    if (ns)
5813      return "xsd:unsignedLong";
5814    return "unsignedLong";
5815  case Ttime:
5816    if (ns)
5817      return "xsd:dateTime";
5818    return "dateTime";
5819  case Tpointer:
5820  case Treference:
5821    return wsdl_type(typ->ref, ns);
5822  case Tarray:
5823    if (ns && *ns)
5824    { s = (char*)emalloc((strlen(ns_convert(ns))+strlen(c_ident(typ))+2)*sizeof(char));
5825      strcpy(s, ns_convert(ns));
5826      strcat(s, ":");
5827      strcat(s, c_ident(typ));
5828      return s;
5829    }
5830    else
5831      return c_ident(typ);
5832  case Tenum:
5833    if (typ->ref == booltable)
5834    { if (ns)
5835        return "xsd:boolean";
5836      return "boolean";
5837    }
5838  case Tstruct:
5839  case Tclass:
5840    if (!has_ns(typ) && ns && *ns)
5841    { s = (char*)emalloc((strlen(ns_convert(ns))+strlen(typ->id->name)+2)*sizeof(char));
5842      strcpy(s, ns_convert(ns));
5843      strcat(s, ":");
5844      strcat(s, ns_convert(typ->id->name));
5845      return s;
5846    }
5847    else if (ns)
5848      return ns_convert(typ->id->name);
5849    else
5850      return ns_remove(typ->id->name);
5851  case Tunion:
5852    if (ns)
5853      return "xsd:choice";
5854    return "choice";
5855  case Ttemplate:
5856    if (typ->ref)
5857      return wsdl_type(typ->ref, ns);
5858    break;
5859  default:
5860    break;
5861  }
5862  return "";
5863}
5864
5865char *
5866the_type(Tnode *typ)
5867{ if (!typ)
5868    return "NULL";
5869  if (typ->type == Tarray || (is_dynamic_array(typ) && (eflag || (!has_ns(typ) && !is_untyped(typ)))))
5870    return "SOAP-ENC:Array";
5871  if (is_string(typ) || is_wstring(typ) || is_stdstring(typ) || is_stdwstring(typ))
5872    return "string";
5873  switch (typ->type)
5874  {
5875  case Tchar:
5876    return "byte";
5877  case Twchar:
5878    return "wchar";
5879  case Tshort:
5880    return "short";
5881  case Tint :
5882    return "int";
5883  case Tlong :
5884  case Tllong :
5885    return "long";
5886  case Tfloat:
5887    return "float";
5888  case Tdouble:
5889    return "double";
5890  case Tldouble:
5891    return "decimal";
5892  case Tuchar:
5893    return "unsignedByte";
5894  case Tushort:
5895    return "unsignedShort";
5896  case Tuint:
5897    return "unsignedInt";
5898  case Tulong:
5899  case Tullong:
5900    return "unsignedLong";
5901  case Ttime:
5902    return "dateTime";
5903  case Tpointer:
5904  case Treference:
5905    return the_type(typ->ref);
5906  case Tarray:
5907    return "SOAP-ENC:Array";
5908  case Tenum:
5909    if (typ->ref == booltable)
5910      return "boolean";
5911  case Tstruct:
5912  case Tclass:
5913    return ns_convert(typ->id->name);
5914  default:
5915    break;
5916  }
5917  return "";
5918}
5919
5920/* c_type returns the type to be used in parameter declaration*/
5921char *
5922c_type(Tnode *typ)
5923{
5924  char *p, *q, tempBuf[10];
5925  Tnode *temp;
5926  if (typ==0)
5927    return "NULL";
5928  switch(typ->type){
5929  case Tnone:
5930    return "";
5931  case Tvoid:
5932    return "void";
5933  case Tchar:
5934    return "char";
5935  case Twchar:
5936    return "wchar_t";
5937  case Tshort:
5938    return "short";
5939  case Tint  :
5940    return "int";
5941  case Tlong  :
5942    return "long";
5943  case Tllong  :
5944    return "LONG64";
5945  case Tfloat:
5946    return "float";
5947  case Tdouble:
5948    return "double";
5949  case Tldouble:
5950    return "long double";
5951  case Tuchar:
5952    return "unsigned char";
5953  case Tushort:
5954    return "unsigned short";
5955  case Tuint:
5956    return "unsigned int";
5957  case Tulong:
5958    return "unsigned long";
5959  case Tullong:
5960    return "ULONG64";
5961  case Ttime:
5962    return "time_t";
5963  case Tstruct:p=(char*) emalloc((8+strlen(ident(typ->id->name))) *sizeof(char));
5964    strcpy(p, "struct ");
5965    strcat(p, ident(typ->id->name));
5966    break;
5967  case Tclass:
5968   p = ident(typ->id->name);
5969   break;
5970  case Tunion: p=(char*) emalloc((7+strlen(ident(typ->id->name))) *sizeof(char));
5971    strcpy(p, "union ");
5972    strcat(p, ident(typ->id->name));
5973    break;
5974  case Tenum:
5975    if (typ->ref == booltable)
5976      return "bool";
5977    p=(char*) emalloc((6+strlen(ident(typ->id->name))) *sizeof(char));
5978    strcpy(p, "enum ");
5979    strcat(p, ident(typ->id->name));
5980    break;
5981  case Tpointer:
5982    p = c_type_id(typ->ref, "*");
5983    break;
5984  case Treference:
5985    p = c_type_id(typ->ref, "&");
5986    break;
5987  case Tarray:
5988    temp = typ;
5989    while(((Tnode*) (typ->ref))->type==Tarray){
5990      typ = typ->ref;
5991    }
5992    p=(char*) emalloc((12+strlen(q = c_type(typ->ref))) *sizeof(char));
5993    if (((Tnode*)typ->ref)->type == Tpointer)
5994      sprintf(p,"%s",c_type(typ->ref));
5995    else
5996      strcpy(p, q);
5997    typ = temp;
5998    while(typ->type==Tarray){
5999      if (((Tnode*) typ->ref)->width)
6000      { sprintf(tempBuf,"[%d]",(typ->width / ((Tnode*) typ->ref)->width));
6001        strcat(p,tempBuf);
6002      }
6003      typ = typ->ref;
6004    }
6005    break;
6006  case Ttemplate:
6007    if (typ->ref)
6008    { p=(char*)emalloc((strlen(q = c_type(typ->ref))+strlen(ident(typ->id->name))+4) *sizeof(char));
6009      strcpy(p, ident(typ->id->name));
6010      strcat(p, "<");
6011      strcat(p, q);
6012      strcat(p, " >");
6013      break;
6014    }
6015  default:
6016    return "UnknownType";
6017  }
6018  return p;
6019}
6020
6021char *
6022c_storage(Storage sto)
6023{ char *p;
6024  static char buf[256];
6025  if (sto & Sconst)
6026  { p = c_storage(sto & ~Sconst);
6027    strcat(p, "const ");
6028    return p;
6029  }
6030  if (sto & Sconstptr)
6031  { p = c_storage(sto & ~Sconstptr);
6032    strcat(p, "const ");
6033    return p;
6034  }
6035  if (sto & Sauto)
6036  { p = c_storage(sto & ~Sauto);
6037    strcat(p, "auto ");
6038    return p;
6039  }
6040  if (sto & Sregister)
6041  { p = c_storage(sto & ~Sregister);
6042    strcat(p, "register ");
6043    return p;
6044  }
6045  if (sto & Sstatic)
6046  { p = c_storage(sto & ~Sstatic);
6047    strcat(p, "static ");
6048    return p;
6049  }
6050  if (sto & Sexplicit)
6051  { p = c_storage(sto & ~Sexplicit);
6052    strcat(p, "explicit ");
6053    return p;
6054  }
6055  if (sto & Sextern)
6056  { p = c_storage(sto & ~Sextern);
6057    return p;
6058  }
6059  if (sto & Stypedef)
6060  { p = c_storage(sto & ~Stypedef);
6061    strcat(p, "typedef ");
6062    return p;
6063  }
6064  if (sto & Svirtual)
6065  { p = c_storage(sto & ~Svirtual);
6066    strcat(p, "virtual ");
6067    return p;
6068  }
6069  if (sto & Sfriend)
6070  { p = c_storage(sto & ~Sfriend);
6071    strcat(p, "friend ");
6072    return p;
6073  }
6074  if (sto & Sinline)
6075  { p = c_storage(sto & ~Sinline);
6076    strcat(p, "inline ");
6077    return p;
6078  }
6079  buf[0]= '\0';
6080  return buf;
6081}
6082
6083char *
6084c_init(Entry *e)
6085{ static char buf[1024];
6086  buf[0] = '\0';
6087  if (e->info.hasval)
6088    switch (e->info.typ->type)
6089    { case Tchar:
6090      case Twchar:
6091      case Tuchar:
6092      case Tshort:
6093      case Tushort:
6094      case Tint:
6095      case Tuint:
6096      case Tlong:
6097      case Tllong:
6098      case Tulong:
6099      case Tullong:
6100      case Ttime:
6101        sprintf(buf, " = "SOAP_LONG_FORMAT, e->info.val.i);
6102	break;
6103      case Tfloat:
6104      case Tdouble:
6105      case Tldouble:
6106        sprintf(buf, " = %f", e->info.val.r);
6107	break;
6108      case Tenum:
6109        sprintf(buf, " = (%s)"SOAP_LONG_FORMAT, c_type(e->info.typ), e->info.val.i);
6110	break;
6111      default:
6112	if (e->info.val.s && strlen(e->info.val.s) < sizeof(buf)-6)
6113          sprintf(buf, " = \"%s\"", cstring(e->info.val.s));
6114	else if (e->info.typ->type == Tpointer)
6115          sprintf(buf, " = NULL");
6116	break;
6117    }
6118  return buf;
6119}
6120
6121/* c_type_id returns the arraytype to be used in parameter declaration
6122   Allows you to specify the identifier that acts acts as teh name of teh
6123   type of array */
6124char *
6125c_type_id(Tnode *typ, char *name)
6126{
6127  char *id,*p,*q,tempBuf[10];
6128  Tnode *temp;
6129  Entry *e;
6130  if (!typ)
6131    return "NULL";
6132  id = ident(name);
6133  switch(typ->type)
6134  {
6135  case Tnone:
6136    p = id;
6137    break;
6138  case Tvoid:
6139    p = (char*)emalloc(6+strlen(id));
6140    strcpy(p, "void ");
6141    strcat(p, id);
6142    break;
6143  case Tchar:
6144    p = (char*)emalloc(6+strlen(id));
6145    strcpy(p, "char ");
6146    strcat(p, id);
6147    break;
6148  case Twchar:
6149    p = (char*)emalloc(9+strlen(id));
6150    strcpy(p, "wchar_t ");
6151    strcat(p, id);
6152    break;
6153  case Tshort:
6154    p = (char*)emalloc(7+strlen(id));
6155    strcpy(p, "short ");
6156    strcat(p, id);
6157    break;
6158  case Tint  :
6159    p = (char*)emalloc(5+strlen(id));
6160    strcpy(p, "int ");
6161    strcat(p, id);
6162    break;
6163  case Tlong  :
6164    p = (char*)emalloc(6+strlen(id));
6165    strcpy(p, "long ");
6166    strcat(p, id);
6167    break;
6168  case Tllong  :
6169    p = (char*)emalloc(8+strlen(id));
6170    strcpy(p, "LONG64 ");
6171    strcat(p, id);
6172    break;
6173  case Tfloat:
6174    p = (char*)emalloc(7+strlen(id));
6175    strcpy(p, "float ");
6176    strcat(p, id);
6177    break;
6178  case Tdouble:
6179    p = (char*)emalloc(8+strlen(id));
6180    strcpy(p, "double ");
6181    strcat(p, id);
6182    break;
6183  case Tldouble:
6184    p = (char*)emalloc(13+strlen(id));
6185    strcpy(p, "long double ");
6186    strcat(p, id);
6187    break;
6188  case Tuchar:
6189    p = (char*)emalloc(15+strlen(id));
6190    strcpy(p, "unsigned char ");
6191    strcat(p, id);
6192    break;
6193  case Tushort:
6194    p = (char*)emalloc(16+strlen(id));
6195    strcpy(p, "unsigned short ");
6196    strcat(p, id);
6197    break;
6198  case Tuint:
6199    p = (char*)emalloc(14+strlen(id));
6200    strcpy(p, "unsigned int ");
6201    strcat(p, id);
6202    break;
6203  case Tulong:
6204    p = (char*)emalloc(15+strlen(id));
6205    strcpy(p, "unsigned long ");
6206    strcat(p, id);
6207    break;
6208  case Tullong:
6209    p = (char*)emalloc(9+strlen(id));
6210    strcpy(p, "ULONG64 ");
6211    strcat(p, id);
6212    break;
6213  case Ttime:
6214    p = (char*)emalloc(8+strlen(id));
6215    strcpy(p, "time_t ");
6216    strcat(p, id);
6217    break;
6218  case Tstruct:
6219    p=(char*) emalloc((9+strlen(ident(typ->id->name))+strlen(id)) *sizeof(char));
6220    strcpy(p, "struct ");
6221    strcat(p, ident(typ->id->name));
6222    strcat(p, " ");
6223    strcat(p, id);
6224    break;
6225  case Tclass:
6226    if (!typ->generated && !is_imported(typ))
6227    { p=(char*) emalloc((8+strlen(ident(typ->id->name))+strlen(id)) *sizeof(char));
6228      strcpy(p, "class ");
6229      strcat(p, ident(typ->id->name));
6230      typ->generated = True;
6231    }
6232    else
6233    { p=(char*) emalloc((2+strlen(ident(typ->id->name))+strlen(id)) *sizeof(char));
6234      strcpy(p, ident(typ->id->name));
6235    }
6236    strcat(p, " ");
6237    strcat(p, id);
6238    break;
6239  case Tunion:
6240    p=(char*) emalloc((8+strlen(ident(typ->id->name))+strlen(id)) *sizeof(char));
6241    strcpy(p, "union ");
6242    strcat(p, ident(typ->id->name));
6243    strcat(p, " ");
6244    strcat(p, id);
6245    break;
6246  case Tenum:
6247    if (typ->ref == booltable)
6248    { p = (char*)emalloc((strlen(id)+6)*sizeof(char));
6249      strcpy(p, "bool ");
6250      strcat(p, id);
6251      return p;
6252    }
6253    p=(char*) emalloc((7+strlen(ident(typ->id->name))+strlen(id)) *sizeof(char));
6254    strcpy(p, "enum ");
6255    strcat(p, ident(typ->id->name));
6256    strcat(p, " ");
6257    strcat(p, id);
6258    break;
6259  case Tpointer:
6260    p = (char*)emalloc(strlen(id)+2);
6261    strcpy(p+1, id);
6262    p[0] = '*';
6263    p = c_type_id(typ->ref, p);
6264    break;
6265  case Treference:
6266    p = (char*)emalloc(strlen(id)+2);
6267    strcpy(p+1, id);
6268    p[0] = '&';
6269    p = c_type_id(typ->ref, p);
6270    break;
6271  case Tarray:
6272    temp = typ;
6273    while(((Tnode*) (typ->ref))->type==Tarray){
6274      typ = typ->ref;
6275    }
6276    p=(char*) emalloc((12+strlen(q = c_type_id(typ->ref, id))) *sizeof(char));
6277    strcpy(p, q);
6278    typ = temp;
6279    while(typ->type==Tarray){
6280      if (((Tnode*) typ->ref)->width)
6281      { sprintf(tempBuf,"[%d]",(typ->width / ((Tnode*) typ->ref)->width));
6282        strcat(p,tempBuf);
6283      }
6284      typ = typ->ref;
6285    }
6286    /*if(((Tnode*) (typ->ref))->type==Tarray){
6287      sprintf(p,"%s [%d]",c_type(typ->ref),(typ->width / ((Tnode*) typ->ref)->width));
6288    }else
6289    sprintf(p,"%s a[%d]",c_type(typ->ref),(typ->width /((Tnode*) typ->ref)->width));*/
6290    break;
6291  case Tfun:
6292    if (strncmp(id, "operator ", 9))
6293      q = c_type_id(((FNinfo*)typ->ref)->ret, id);
6294    else
6295      q = id;
6296    p = (char*)emalloc(1024);
6297    strcpy(p, q);
6298    strcat(p, "(");
6299    for (e = ((FNinfo*)typ->ref)->args->list; e; e = e->next)
6300    { strcat(p, c_storage(e->info.sto));
6301      if (e->info.typ->type != Tvoid)
6302      { strcat(p, c_type_id(e->info.typ, e->sym->name));
6303        strcat(p, c_init(e));
6304      }
6305      else
6306        strcat(p, "void");
6307      if (e->next)
6308        strcat(p, ", ");
6309    }
6310    strcat(p, ")");
6311    break;
6312  case Ttemplate:
6313    if (typ->ref)
6314    { p=(char*)emalloc((strlen(q = c_type(typ->ref))+strlen(ident(typ->id->name))+strlen(id)+4) *sizeof(char));
6315      strcpy(p, ident(typ->id->name));
6316      strcat(p, "<");
6317      strcat(p, q);
6318      strcat(p, " >");
6319      strcat(p, id);
6320      break;
6321    }
6322  default:
6323    return "UnknownType";
6324  }
6325  return p;
6326}
6327
6328char *
6329xsi_type_Tarray(Tnode *typ)
6330{ Tnode *t;
6331  int cardinality;
6332  char *p, *s;
6333  t = typ->ref;
6334  cardinality = 1;
6335  while (t->type == Tarray || (is_dynamic_array(t) && !has_ns(t) && !is_untyped(typ)))
6336  { if( t->type == Tarray)
6337      t = t->ref;
6338    else
6339      t = ((Table*)t->ref)->list->info.typ->ref;
6340    cardinality++;
6341  }
6342  s = xsi_type(t);
6343  if (!*s)
6344    s = wsdl_type(t, "");
6345  p = (char*)emalloc(strlen(s)+cardinality+3);
6346  strcpy(p, s);
6347  if (cardinality > 1)
6348  { strcat(p, "[");
6349    for (; cardinality > 2; cardinality--)
6350      strcat(p, ",");
6351    strcat(p, "]");
6352  }
6353  /*
6354  for (; cardinality; cardinality--)
6355  { t = typ;
6356    for (i = 1; i < cardinality; i++)
6357      t = t->ref;
6358    sprintf(temp,"[%d]",get_dimension(t));
6359    strcat(p, temp);
6360  }
6361  */
6362  return p;
6363}
6364
6365char *
6366xsi_type_Darray(Tnode *typ)
6367{ Tnode *t;
6368  Entry *q;
6369  int cardinality;
6370  char *p, *s;
6371  if (!typ->ref)
6372    return "";
6373  q = ((Table*)typ->ref)->list;
6374  while (q && q->info.typ->type == Tfun)
6375    q = q->next;
6376  t = q->info.typ->ref;
6377  cardinality = 1;
6378  while (t->type == Tarray || (is_dynamic_array(t) && !has_ns(t) && !is_untyped(typ)))
6379  { if (t->type == Tarray)
6380      t = t->ref;
6381    else
6382    { q = ((Table*)t->ref)->list;
6383      while (q && q->info.typ->type == Tfun)
6384        q = q->next;
6385      t = q->info.typ->ref;
6386    }
6387    cardinality++;
6388  }
6389  s = xsi_type(t);
6390  if (!*s)
6391    s = wsdl_type(t, "");
6392  p = (char*)emalloc(strlen(s)+cardinality*2+1);
6393  strcpy(p, s);
6394  if (cardinality > 1)
6395  { strcat(p, "[");
6396    for (; cardinality > 2; cardinality--)
6397      strcat(p, ",");
6398    strcat(p, "]");
6399  }
6400  return p;
6401}
6402
6403void
6404out_generate(Tnode *typ)
6405{
6406	if (is_transient(typ) || typ->type == Twchar || is_XML(typ) || is_void(typ))
6407	  return;
6408	if (lflag && typ->type == Tint && !typ->sym)
6409	{ fprintf(fhead,"\n\n#ifndef %s",soap_type(typ));
6410	  fprintf(fhead,"\n#define %s (%d)",soap_type(typ),typ->num);
6411	  fprintf(fhead,"\n#endif");
6412          fprintf(fhead,"\n\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_int(struct soap*, int*);");
6413          fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_int(struct soap*, const char*, int, const int*, const char*);");
6414          fprintf(fhead,"\nSOAP_FMAC1 int* SOAP_FMAC2 soap_in_int(struct soap*, const char*, int*, const char*);");
6415	  return; /* do not generate int serializers in libs */
6416	}
6417	else if (is_imported(typ) && (typ->type != Tint || typ->sym))
6418	  return;
6419	if (is_primitive(typ) || is_string(typ) || is_wstring(typ))
6420	{	      /* typeNO++; */
6421		      fprintf(fhead,"\n\n#ifndef %s",soap_type(typ));
6422		      fprintf(fhead,"\n#define %s (%d)",soap_type(typ),typ->num);
6423		      fprintf(fhead,"\n#endif");
6424			fflush(fhead);
6425			defaults(typ);
6426			mark(typ);
6427			soap_put(typ);
6428			soap_out(typ);
6429			soap_get(typ);
6430			soap_in(typ);
6431	  return;
6432	}
6433        switch(typ->type)
6434        {
6435	  case Ttemplate:
6436	  case Tenum:
6437          case Tpointer:
6438          case Tarray:
6439          case Tstruct:
6440	  case Tclass:
6441          case Tunion:
6442  			if (is_header_or_fault(typ) || is_body(typ))
6443			{ fprintf(fhead,"\n\n#ifndef WITH_NOGLOBAL");
6444			  fprintf(fout,"\n\n#ifndef WITH_NOGLOBAL");
6445		        }
6446		      fprintf(fhead,"\n\n#ifndef %s",soap_type(typ));
6447		      fprintf(fhead,"\n#define %s (%d)",soap_type(typ),typ->num);
6448		      fprintf(fhead,"\n#endif");
6449		      fflush(fhead);
6450		      defaults(typ);
6451                      mark(typ);
6452		      soap_put(typ);
6453		      soap_out(typ);
6454		      soap_get(typ);
6455		      soap_in(typ);
6456		      if (typ->type == Tstruct || typ->type == Tclass || typ->type == Ttemplate)
6457		        soap_instantiate_class(typ);
6458  		      if (is_header_or_fault(typ) || is_body(typ))
6459    		      { fprintf(fhead,"\n\n#endif");
6460    		        fprintf(fout,"\n\n#endif");
6461		      }
6462                      break;
6463              default:break;
6464         }
6465}
6466
6467void
6468matlab_gen_sparseStruct(void)
6469{
6470  fprintf(fmheader,"\nstruct soapSparseArray{\n");
6471  fprintf(fmheader,"  int *ir;\n");
6472  fprintf(fmheader,"  int *jc;\n");
6473  fprintf(fmheader,"  double *pr;\n");
6474  fprintf(fmheader,"  int num_columns;\n");
6475  fprintf(fmheader,"  int num_rows;\n");
6476  fprintf(fmheader,"  int nzmax;\n");
6477  fprintf(fmheader,"};\n");
6478}
6479
6480void
6481matlab_c_to_mx_sparse(void)
6482{
6483  fprintf(fmheader,"\nmxArray* c_to_mx_soapSparseArray(struct soapSparseArray);\n");
6484  fprintf(fmatlab,"\nmxArray* c_to_mx_soapSparseArray(struct soapSparseArray a)\n");
6485  fprintf(fmatlab,"{\n");
6486  fprintf(fmatlab,"  mxArray *b;\n");
6487  fprintf(fmatlab,"  b = mxCreateSparse(a.num_rows, a.num_columns, a.nzmax, mxREAL);\n");
6488  fprintf(fmatlab,"  mxSetIr(b,a.ir);\n");
6489  fprintf(fmatlab,"  mxSetJc(b,a.jc);\n");
6490  fprintf(fmatlab,"  mxSetPr(b,a.pr);\n");
6491  fprintf(fmatlab,"  return b;\n");
6492  fprintf(fmatlab,"}\n");
6493}
6494
6495void
6496matlab_mx_to_c_sparse(void)
6497{
6498  fprintf(fmheader,"\nmxArray* mx_to_c_soapSparseArray(const mxArray *, struct soapSparseArray *);\n");
6499  fprintf(fmatlab,"\nmxArray* mx_to_c_soapSparseArray(const mxArray *a, struct soapSparseArray *b)\n");
6500  fprintf(fmatlab,"{\n");
6501  fprintf(fmatlab,"  if(!mxIsSparse(a))\n");
6502  fprintf(fmatlab,"    {\n");
6503  fprintf(fmatlab,"      mexErrMsgTxt(\"Input should be a sparse array.\");\n");
6504  fprintf(fmatlab,"    }\n");
6505
6506  fprintf(fmatlab,"  /* Get the starting positions of the data in the sparse array. */  \n");
6507  fprintf(fmatlab,"  b->pr = mxGetPr(a);\n");
6508  fprintf(fmatlab,"  b->ir = mxGetIr(a);\n");
6509  fprintf(fmatlab,"  b->jc = mxGetJc(a);\n");
6510  fprintf(fmatlab,"  b->num_columns = mxGetN(a);\n");
6511  fprintf(fmatlab,"  b->num_rows = mxGetM(a);\n");
6512  fprintf(fmatlab,"  b->nzmax = mxGetNzmax(a);\n");
6513  fprintf(fmatlab,"}\n");
6514}
6515
6516void
6517matlab_mx_to_c_dynamicArray(typ)
6518Tnode* typ;
6519{
6520  int d;
6521  Entry *p;
6522
6523  p = is_dynamic_array(typ);
6524
6525  fprintf(fmatlab,"{\n");
6526  fprintf(fmatlab,"\tint i, numdims;\n");
6527  fprintf(fmatlab,"\tconst int *dims;\n");
6528  fprintf(fmatlab,"\tdouble *temp;\n");
6529  fprintf(fmatlab,"\tint size = 1;\n");
6530  fprintf(fmatlab,"\tint ret;\n");
6531  fprintf(fmatlab,"\tnumdims = mxGetNumberOfDimensions(a);\n");
6532  fprintf(fmatlab,"\tdims = mxGetDimensions(a);\n");
6533
6534  d = get_Darraydims(typ);
6535  fprintf(fmatlab,"\tif (numdims != %d)\n", d);
6536  fprintf(fmatlab,"\t\tmexErrMsgTxt(\"Incompatible array specifications in C and mx.\");\n");
6537
6538  /*
6539  fprintf(fmatlab,"\tfor(i=0;i<numdims; i++) {\n");
6540  fprintf(fmatlab,"\t  b->__size[i] = dims[i];\n");
6541  fprintf(fmatlab,"\t}\n");
6542  */
6543
6544  if((((Tnode *)p->info.typ->ref)->type != Tchar) && (((Tnode *)p->info.typ->ref)->type != Tuchar))
6545    {
6546      fprintf(fmatlab,"\ttemp = (double*)mxGetPr(a);\n");
6547      fprintf(fmatlab,"\tif (!temp)\n\t\tmexErrMsgTxt(\"mx_to_c_ArrayOfdouble: Pointer to data is NULL\");\n");
6548    }
6549
6550  fprintf(fmatlab,"\tfor (i = 0; i < numdims; i++) {\n");
6551  fprintf(fmatlab,"\t\tif (b->__size[i] < dims[i])\n");
6552  fprintf(fmatlab,"\t\t\tmexErrMsgTxt(\"Incompatible array dimensions in C and mx.\");\n");
6553  fprintf(fmatlab,"\t\tsize *= dims[i];\n");
6554  fprintf(fmatlab,"\t}\n");
6555
6556  if((((Tnode *)p->info.typ->ref)->type != Tchar) && (((Tnode *)p->info.typ->ref)->type != Tuchar))
6557    {
6558      fprintf(fmatlab,"\tfor (i = 0; i < size; i++)\n");
6559      fprintf(fmatlab,"\t\tb->__ptr[i] = (%s)*temp++;\n", c_type(p->info.typ->ref));
6560    }
6561  else
6562    {
6563      fprintf(fmatlab,"\tret = mxGetString(a, b->__ptr, size + 1);\n");
6564      fprintf(fmatlab,"\tmexPrintf(\"ret = %%d, b->__ptr = %%s, size = %%d\", ret, b->__ptr, size);\n");
6565    }
6566  fprintf(fmatlab,"\n}\n");
6567
6568  fflush(fmatlab);
6569}
6570
6571
6572void
6573matlab_c_to_mx_dynamicArray(typ)
6574Tnode* typ;
6575{
6576  int d,i;
6577  Entry *p;
6578
6579  p = is_dynamic_array(typ);
6580
6581  fprintf(fmatlab,"{\n");
6582  fprintf(fmatlab,"\tmxArray *out;\n");
6583  fprintf(fmatlab,"\t%s;\n",c_type_id(p->info.typ->ref,"*temp"));
6584  d = get_Darraydims(typ);
6585  fprintf(fmatlab,"\tint i;\n");
6586
6587  fprintf(fmatlab,"\tint ndim = %d, dims[%d] = {", d, d);
6588  for (i = 0; i < d; i++)
6589    {
6590      if(i==0)
6591	fprintf(fmatlab,"a.__size[%d]",i);
6592      else
6593	fprintf(fmatlab,", a.__size[%d]",i);
6594    }
6595  fprintf(fmatlab,"};\n");
6596
6597  fprintf(fmatlab,"\tint size = ");
6598   for (i = 0; i < d; i++)
6599    {
6600      if(i==0)
6601	fprintf(fmatlab,"dims[%d]",i);
6602      else
6603	fprintf(fmatlab,"*dims[%d]",i);
6604    }
6605   fprintf(fmatlab,";\n");
6606   if((((Tnode *)p->info.typ->ref)->type != Tchar) && (((Tnode *)p->info.typ->ref)->type != Tuchar))
6607     {
6608       fprintf(fmatlab,"\tout = mxCreateNumericArray(ndim, dims, %s, mxREAL);\n",get_mxClassID(p->info.typ->ref));
6609       fprintf(fmatlab,"\tif (!out)\n\t\tmexErrMsgTxt(\"Could not create mxArray.\");\n");
6610       fprintf(fmatlab,"\ttemp = (%s) mxGetPr(out);\n",c_type_id(p->info.typ->ref,"*"));
6611       fprintf(fmatlab,"\tif (!temp)\n\t\tmexErrMsgTxt(\"matlab_array_c_to_mx: Pointer to data is NULL\");\n");
6612
6613       fprintf(fmatlab,"\tfor (i = 0; i < size; i++)\n");
6614       fprintf(fmatlab,"\t\t*temp++ = a.__ptr[i];\n");
6615     }
6616   else
6617     {
6618       fprintf(fmatlab,"\tout = mxCreateString(a.__ptr);\n");
6619       fprintf(fmatlab,"\tif (!out)\n\t\tmexErrMsgTxt(\"Could not create mxArray.\");\n");
6620     }
6621  fprintf(fmatlab,"\treturn out;\n}\n");
6622  fflush(fmatlab);
6623}
6624
6625char*
6626get_mxClassID(Tnode* typ)
6627{
6628
6629  switch(typ->type)
6630    {
6631    case Tdouble:
6632      return "mxDOUBLE_CLASS";
6633    case Tfloat:
6634      return "mxSINGLE_CLASS";
6635    case Tshort:
6636      return "mxINT16_CLASS";
6637    case Tushort:
6638      return "mxUINT16_CLASS";
6639    case Tint:
6640      return "mxINT32_CLASS";
6641    case Tuint:
6642      return "mxUINT32_CLASS";
6643    case Tlong:
6644      return "mxINT32_CLASS";
6645    case Tulong:
6646      return "mxUINT32_CLASS";
6647    case Tllong:
6648      return "mxINT64_CLASS";
6649    case Tullong:
6650      return "mxUINT64_CLASS";
6651    case Tchar:
6652      return "mxCHAR_CLASS";
6653    case Tuchar:
6654      return "mxCHAR_CLASS";
6655    default:
6656      return "";
6657    };
6658}
6659
6660/*Function not in use.*/
6661void
6662matlab_array_c_to_mx(typ)
6663Tnode* typ;
6664{
6665  Tnode* temp;
6666  int d,i;
6667
6668  fprintf(fmatlab,"{\n\tint rows, r, cols, c;\n");
6669  fprintf(fmatlab,"\tmxArray* out;\n");
6670  fprintf(fmatlab,"\tdouble* temp;\n");
6671  d = get_dimension(typ);
6672  fprintf(fmatlab,"\tint ndim = %d, dims[%d] = {",d,d);
6673  temp=typ;
6674  for(i=0;i<d; i++)
6675    {
6676      if(i==0)
6677	fprintf(fmatlab,"%d",temp->width / ((Tnode*) temp->ref)->width);
6678      else
6679	fprintf(fmatlab,",%d",temp->width / ((Tnode*) temp->ref)->width);
6680      temp=typ->ref;
6681    }
6682  fprintf(fmatlab,"};\n");
6683
6684  fprintf(fmatlab,"\tout = mxCreateNumericArray(ndim, dims, mxDOUBLE_CLASS, mxREAL);\n");
6685  fprintf(fmatlab,"\ttemp = (double *) mxGetPr(out);\n");
6686  fprintf(fmatlab,"\tif (!out)\n\t\tmexErrMsgTxt(\"Could not create mxArray.\");\n");
6687  fprintf(fmatlab,"\tif (!temp)\n\t\tmexErrMsgTxt(\"matlab_array_c_to_mx: Pointer to data is NULL\");\n");
6688  fprintf(fmatlab,"\trows = mxGetM(out);\n");
6689  fprintf(fmatlab,"\tif (!rows)\n\t\tmexErrMsgTxt(\"matlab_array_c_to_mx: Data has zero rows\");\n");
6690  fprintf(fmatlab,"\tcols = mxGetN(out);\n");
6691  fprintf(fmatlab,"\tif (!cols)\n\t\tmexErrMsgTxt(\"matlab_array_c_to_mx: Data has zero columns\");\n");
6692  fprintf(fmatlab,"\tfor (c = 0; c < cols; c++)\n");
6693  fprintf(fmatlab,"\t\tfor (r = 0; r < rows; r++)\n");
6694  fprintf(fmatlab,"\t\t\t*temp++ = z->a[r][c];\n");
6695  fprintf(fmatlab,"\treturn out;\n}\n");
6696  fflush(fmatlab);
6697}
6698
6699
6700void matlab_c_to_mx_pointer(typ)
6701Tnode* typ;
6702{
6703  if (!typ->ref)
6704    return;
6705
6706  /*  if(((Tnode*)typ->ref)->type == Tstruct)
6707    {
6708      fprintf(fmheader,"\nmxArray* c_to_mx_%s(%s);\n",c_ident(typ),c_type_id(typ, "*"));
6709      fprintf(fmatlab,"\nmxArray* c_to_mx_%s(%s)\n",c_ident(typ),c_type_id(typ, "*a"));
6710    }
6711  else
6712  {*/
6713  fprintf(fmheader,"\nmxArray* c_to_mx_%s(%s);\n",c_ident(typ),c_type_id(typ, ""));
6714  fprintf(fmatlab,"\nmxArray* c_to_mx_%s(%s)\n",c_ident(typ),c_type_id(typ, "a"));
6715      /*  }*/
6716  fprintf(fmatlab,"{\n");
6717  fprintf(fmatlab,"\tmxArray  *fout;\n");
6718  fprintf(fmatlab,"\tfout = c_to_mx_%s(*a);\n",c_ident(typ->ref));
6719  fprintf(fmatlab,"\treturn fout;\n");
6720  fprintf(fmatlab,"}\n");
6721}
6722
6723void matlab_mx_to_c_pointer(typ)
6724Tnode* typ;
6725{
6726  if (!typ->ref)
6727    return;
6728  fprintf(fmheader,"\nvoid mx_to_c_%s(const mxArray*,%s);\n",c_ident(typ),c_type_id(typ, "*"));
6729  fprintf(fmatlab,"\nvoid mx_to_c_%s(const mxArray* a,%s)\n",c_ident(typ),c_type_id(typ, "*b"));
6730  fprintf(fmatlab,"{\n\tmx_to_c_%s(a,*b);\n",c_ident(typ->ref));
6731  fprintf(fmatlab,"\n}\n");
6732}
6733
6734void func2(typ)
6735Tnode* typ;
6736{
6737  Table *table,*t;
6738  Entry *p;
6739
6740  fprintf(fmatlab,"\tif(!mxIsStruct(a))\n\t\tmexErrMsgTxt(\"Input must be a structure.\");\n");
6741
6742  table=(Table*)typ->ref;
6743  for (t = table; t != (Table *) 0; t = t->prev) {
6744    for (p = t->list; p != (Entry*) 0; p = p->next) {
6745      if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
6746	{
6747	  fprintf(fmatlab,"\t{mxArray *tmp = mxGetField(a,0,\"%s\");\n",ident(p->sym->name));
6748	  fprintf(fmatlab,"\tif (!tmp) {\n");
6749	  fprintf(fmatlab,"\t\tmexErrMsgTxt(\"Above field is empty!\");\n\t}\n");
6750	  fprintf(fmatlab,"\tmx_to_c_%s(tmp,&(b->%s));}\n",c_ident(p->info.typ),ident(p->sym->name));
6751	}
6752    }
6753  }
6754}
6755
6756void
6757matlab_mx_to_c_struct(typ)
6758Tnode* typ;
6759{
6760  if (!typ->ref)
6761    return;
6762
6763
6764  if (is_dynamic_array(typ))
6765    {
6766      fprintf(fmheader,"\nvoid mx_to_c_%s(const mxArray*, %s);\n",c_ident(typ),c_type_id(typ, "*"));
6767      fprintf(fmatlab,"\nvoid mx_to_c_%s(const mxArray* a, %s)\n",c_ident(typ),c_type_id(typ, "*b"));
6768      matlab_mx_to_c_dynamicArray(typ);
6769      return;
6770    }
6771  else if(strstr(c_type_id(typ, ""),"soapSparseArray"))
6772    {
6773      return;
6774    }
6775
6776  fprintf(fmheader,"\nvoid mx_to_c_%s(const mxArray*, %s);\n",c_ident(typ),c_type_id(typ, "*"));
6777  fprintf(fmatlab,"\nvoid mx_to_c_%s(const mxArray* a, %s)\n",c_ident(typ),c_type_id(typ, "*b"));
6778  fprintf(fmatlab,"{\n");
6779
6780  func2(typ);
6781  fprintf(fmatlab,"\n}\n");
6782
6783  return;
6784}
6785
6786
6787
6788void
6789matlab_c_to_mx_struct(typ)
6790Tnode* typ;
6791{
6792  Table *table,*t;
6793  Entry *p;
6794  int number_of_fields=0;
6795
6796  if (!typ->ref)
6797    return;
6798
6799  if (is_dynamic_array(typ))
6800    {
6801      fprintf(fmheader,"\nmxArray* c_to_mx_%s(%s);\n",c_ident(typ),c_type_id(typ, ""));
6802      fprintf(fmatlab,"\nmxArray* c_to_mx_%s(%s)\n",c_ident(typ),c_type_id(typ, "a"));
6803      matlab_c_to_mx_dynamicArray(typ);
6804      return;
6805    }
6806  else if(strstr(c_type_id(typ, ""),"soapSparseArray"))
6807    {
6808      return;
6809    }
6810
6811  fprintf(fmheader,"\nmxArray* c_to_mx_%s(%s);\n",c_ident(typ),c_type_id(typ, ""));
6812  fprintf(fmatlab,"\nmxArray* c_to_mx_%s(%s)\n",c_ident(typ),c_type_id(typ, "a"));
6813  table=(Table*)typ->ref;
6814  fprintf(fmatlab,"{\n\tconst char* fnames[] = {");
6815  for (t = table; t != (Table *) 0; t = t->prev) {
6816    for (p = t->list; p != (Entry*) 0; p = p->next) {
6817      if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
6818	{
6819	  if(number_of_fields)
6820	    fprintf(fmatlab,",\"%s\"",ident(p->sym->name));
6821	  else
6822	    fprintf(fmatlab,"\"%s\"",ident(p->sym->name));
6823	  number_of_fields++;
6824	}
6825    }
6826  }
6827  fprintf(fmatlab,"}; /* pointers to field names*/\n");
6828
6829  fprintf(fmatlab,"\tint rows = 1, cols = 1;\n\tint index = 0;\n\tint number_of_fields = %d;\n\tmxArray *struct_array_ptr;\n",number_of_fields);
6830  fprintf(fmatlab,"\t/* Create a 1x1 struct matrix for output  */\n");
6831  fprintf(fmatlab,"\tstruct_array_ptr = mxCreateStructMatrix(rows, cols, number_of_fields, fnames);\n\tmexPrintf(\"6\");\n\tif(struct_array_ptr == NULL) {\n\t\tmexPrintf(\"COULDNT CREATE A MATRIX\");}\n\tmexPrintf(\"7\");\n");
6832
6833
6834  for (t = table; t != (Table *) 0; t = t->prev) {
6835    for (p = t->list; p != (Entry*) 0; p = p->next) {
6836      if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
6837	{
6838	  fprintf(fmatlab,"\t{mxArray *fout = c_to_mx_%s(a.%s);\n",c_ident(p->info.typ), ident(p->sym->name));
6839	  fprintf(fmatlab,"\tmxSetField(struct_array_ptr, index,\"%s\" , fout);}\n", ident(p->sym->name));
6840	}
6841    }
6842  }
6843  fprintf(fmatlab,"\treturn struct_array_ptr;\n}\n");
6844  return;
6845}
6846/*
6847char*
6848matlab_c_to_mx(typ)
6849Tnode* typ;
6850{
6851
6852  switch(typ->type)
6853    {
6854    case Tstruct:
6855      break;
6856    case Tarray:
6857      matlab_array_c_to_mx(typ);break;
6858    case Tpointer:
6859      fprintf(fmheader,"\npointer in matlab_c_to_mx\n");break;
6860    default:break;
6861    }
6862
6863  return NULL;
6864}
6865*/
6866
6867void
6868matlab_c_to_mx_primitive(typ)
6869Tnode *typ;
6870{
6871  fprintf(fmheader,"\nmxArray* c_to_mx_%s(%s);",c_ident(typ),c_type_id(typ, ""));
6872  fprintf(fmatlab,"\nmxArray* c_to_mx_%s(%s)\n",c_ident(typ),c_type_id(typ, "a"));
6873
6874  fprintf(fmatlab,"{\n\tmxArray  *fout;\n");
6875  if((typ->type == Tchar) || (typ->type == Tuchar))
6876    {
6877      fprintf(fmatlab,"\tchar buf[2];\n");
6878      fprintf(fmatlab,"\tbuf[0] = a;\n");
6879      fprintf(fmatlab,"\tbuf[1] = \'\\0\';\n");
6880      fprintf(fmatlab,"\tfout = mxCreateString(buf);\n");
6881      fprintf(fmatlab,"\tif (!fout)\n");
6882      fprintf(fmatlab,"\t\tmexErrMsgTxt(\"Could not create mxArray.\");\n");
6883    }
6884  else
6885    {
6886      fprintf(fmatlab,"\tint ndim = 1, dims[1] = {1};\n");
6887      fprintf(fmatlab,"\tfout = mxCreateNumericArray(ndim, dims, %s, mxREAL);\n",get_mxClassID(typ));
6888      fprintf(fmatlab,"\t%s = (%s)mxGetPr(fout);\n",c_type_id(typ,"*temp"),c_type_id(typ,"*"));
6889      fprintf(fmatlab,"\tif (!fout)\n");
6890      fprintf(fmatlab,"\t\tmexErrMsgTxt(\"Could not create mxArray.\");\n");
6891      fprintf(fmatlab,"\tif (!temp) \n");
6892      fprintf(fmatlab,"\t\tmexErrMsgTxt(\"matlab_array_c_to_mx: Pointer to data is NULL\");\n");
6893      fprintf(fmatlab,"\t*temp++= a;\n");
6894    }
6895  fprintf(fmatlab,"\treturn fout;\n}\n");
6896}
6897
6898void
6899matlab_mx_to_c_primitive(typ)
6900Tnode *typ;
6901{
6902  fprintf(fmheader, "\nvoid mx_to_c_%s(const mxArray *, %s);\n",c_ident(typ),c_type_id(typ, "*"));
6903  fprintf(fmatlab, "\nvoid mx_to_c_%s(const mxArray *a, %s)\n",c_ident(typ),c_type_id(typ, "*b"));
6904  if((typ->type == Tchar) || (typ->type == Tuchar))
6905    {
6906      fprintf(fmatlab,"{\n\tint ret;\n");
6907      fprintf(fmatlab,"\tchar buf[2];\n");
6908      fprintf(fmatlab,"\tret = mxGetString(a, buf, 2);\n");
6909      fprintf(fmatlab,"\tmexPrintf(\"ret = %%d, buf = %%s\", ret, buf);\n");
6910      fprintf(fmatlab,"\t*b = buf[0];\n");
6911    }
6912  else
6913    {
6914      fprintf(fmatlab,"{\n\tdouble* data = (double*)mxGetData(a);\n");
6915      fprintf(fmatlab,"\t*b = (%s)*data;\n",c_type(typ));
6916    }
6917      fprintf(fmatlab,"\n}\n");
6918}
6919
6920void
6921matlab_out_generate(typ)
6922Tnode *typ;
6923{
6924
6925  if (is_transient(typ) || typ->type == Twchar || is_XML(typ))
6926    return;
6927
6928  /*
6929  typeNO++;
6930  if (typeNO>=1024)
6931    execerror("Too many user-defined data types");
6932    */
6933
6934  if(is_primitive(typ))
6935    {
6936      matlab_c_to_mx_primitive(typ);
6937      matlab_mx_to_c_primitive(typ);
6938      return;
6939    }
6940
6941  switch(typ->type)
6942    {
6943    case Tstruct:
6944      matlab_c_to_mx_struct(typ);
6945      matlab_mx_to_c_struct(typ);
6946      break;
6947    case Tpointer:
6948      matlab_c_to_mx_pointer(typ);
6949      matlab_mx_to_c_pointer(typ);
6950      break;
6951    case Tarray:
6952      break;
6953    default:break;
6954    }
6955}
6956
6957/*his function is called first it first generates all routines
6958  and then in the second pass calls all routines to generate
6959  matlab_out for the table*/
6960
6961void
6962func1(Table *table, Entry *param)
6963{ Entry *q,*pout,*response=NULL;
6964  Table *output;
6965  q=entry(table, param->sym);
6966  if (q)
6967    pout = (Entry*)q->info.typ->ref;
6968  else
6969  { fprintf(stderr, "Internal error: no table entry\n");
6970    return;
6971  }
6972  q=entry(classtable, param->sym);
6973  output=(Table*) q->info.typ->ref;
6974  if (!is_response(pout->info.typ))
6975  { response = get_response(param->info.typ);
6976  }
6977  fprintf(fmheader,"\n\toutside loop struct %s soap_tmp_%s;",param->sym->name,param->sym->name);
6978  if (!is_response(pout->info.typ) && response)
6979  { fprintf(fmheader,"\n\tif..inside loop struct %s *soap_tmp_%s;",c_ident(response->info.typ), c_ident(response->info.typ));
6980  }
6981  fflush(fmheader);
6982}
6983
6984void
6985matlab_def_table(Table *table)
6986{
6987  Entry *q,*pout,*e,*response=NULL;
6988  int i;
6989  Tnode *p;
6990
6991  /*  for (q1 = table->list; q1 != (Entry*) 0; q1 = q1->next)
6992    if (q1->info.typ->type==Tfun)
6993      func1(table, q1);
6994  */
6995
6996  /* Sparse matrix code will be present by default */
6997  matlab_gen_sparseStruct();
6998  matlab_c_to_mx_sparse();
6999  matlab_mx_to_c_sparse();
7000
7001  for(i=0;i<TYPES;i++)
7002    for(p=Tptr[i];p!=(Tnode*) 0;p=p->next)
7003      {
7004	/* This is generated for everything declared in the ".h" file. To make
7005	   sure that it doesnt get generated for functions do a comparison with
7006	   p->sym->name, so that its not generated for functions.
7007	*/
7008	if(is_XML(p))
7009	  continue;
7010	if(strstr(c_ident(p),"SOAP_ENV_") != NULL)
7011	  continue;
7012	for(q = table->list; q != (Entry*) 0; q = q->next)
7013	  {
7014	    if(strcmp(c_ident(p),q->sym->name) == 0)
7015	      break;
7016	    e=entry(table, q->sym);
7017	    if (e)
7018	      pout = (Entry*)e->info.typ->ref;
7019	    else
7020	    { fprintf(stderr, "Internal error: no table entry\n");
7021	      return;
7022	    }
7023	    if (!is_response(pout->info.typ))
7024	    { response = get_response(q->info.typ);
7025	    }
7026	    if (!is_response(pout->info.typ) && response)
7027	    {
7028	      if(strcmp(c_ident(p),c_ident(response->info.typ)) == 0)
7029		 break;
7030	    }
7031	  }
7032	if(q == (Entry*) 0)
7033	  matlab_out_generate(p);
7034      }
7035}
7036
7037void
7038def_table(Table *table)
7039{ int i;
7040  Tnode *p;
7041  for (i = 0; i < TYPES; i++)
7042    for (p = Tptr[i]; p; p = p->next)
7043      out_generate(p);
7044}
7045
7046
7047int
7048no_of_var(typ)
7049Tnode * typ;
7050{
7051  Entry *p;
7052  Table *t;
7053  int i=0;
7054  if(typ->type==Tstruct || typ->type==Tclass)
7055    {
7056      t=typ->ref;
7057      for (p = t->list; p != (Entry*) 0; p = p->next) {
7058	if(p->info.typ->type==Tpointer)
7059	  i++;
7060      }
7061    }
7062  if((((Tnode *)(typ->ref))->type==Tstruct) ||
7063     (((Tnode *)(typ->ref))->type==Tclass) )
7064    {
7065      t=((Tnode*)(typ->ref))->ref;
7066      for (p = t->list; p != (Entry*) 0; p = p->next) {
7067	if(p->info.typ->type==Tpointer)
7068	  i++;
7069      }
7070    }
7071  return i;
7072}
7073
7074void
7075in_defs(Table *table)
7076{ int i;
7077  Tnode *p;
7078  for (i = 0; i < TYPES; i++)
7079  { for (p = Tptr[i]; p; p = p->next)
7080    { if (!is_element(p) && !is_transient(p) && p->type != Twchar && p->type != Tfun && p->type != Treference && p->type != Tunion && !is_XML(p) && !is_header_or_fault(p) && !is_body(p) && !is_template(p))
7081      { char *s = xsi_type(p);
7082        if (!*s)
7083          s = wsdl_type(p, "");
7084	if (*s == '-')
7085	  continue;
7086	if (is_string(p))
7087          fprintf(fout,"\n\tcase %s:\n\t{\tchar **s;\n\t\ts = soap_in_%s(soap, NULL, NULL, \"%s\");\n\t\treturn s ? *s : NULL;\n\t}", soap_type(p), c_ident(p), s);
7088	else if (is_wstring(p))
7089          fprintf(fout,"\n\tcase %s:\n\t{\twchar_t **s;\n\t\ts = soap_in_%s(soap, NULL, NULL, \"%s\");\n\t\treturn s ? *s : NULL;\n\t}", soap_type(p), c_ident(p), s);
7090	else
7091          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_in_%s(soap, NULL, NULL, \"%s\");", soap_type(p), c_ident(p), s);
7092      }
7093    }
7094  }
7095}
7096
7097void
7098in_defs2(Table *table)
7099{ int i, j;
7100  Tnode *p;
7101  char *s;
7102  for (i = 0; i < TYPES; i++)
7103  { /* make sure (wrapper) classes are checked first */
7104    if (i == 0)
7105      j = Tclass;
7106    else if (i == Tclass)
7107      continue;
7108    else
7109      j = i;
7110    for (p = Tptr[j]; p; p = p->next)
7111    { if (!is_element(p) && ((!is_transient(p) && !is_template(p) && p->type != Twchar && p->type != Tfun && p->type != Tpointer && p->type != Treference && p->type != Tunion && !is_XML(p) && !is_header_or_fault(p) && !is_body(p)) || (is_string(p) && !is_XML(p))))
7112      { s = xsi_type(p);
7113	if (!*s)
7114	  s = wsdl_type(p, "");
7115	if (*s == '-')
7116	  continue;
7117	if (*s)
7118	{ if (is_dynamic_array(p) && !is_binary(p) && !has_ns(p) && !is_untyped(p))
7119	    fprintf(fout,"\n\t\tif (*soap->arrayType && !soap_match_array(soap, \"%s\"))\n\t\t{\t*type = %s;\n\t\t\treturn soap_in_%s(soap, NULL, NULL, NULL);\n\t\t}", s, soap_type(p), c_ident(p));
7120	  else if (is_string(p))
7121	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\tchar **s;\n\t\t\t*type = %s;\n\t\t\ts = soap_in_%s(soap, NULL, NULL, NULL);\n\t\t\treturn s ? *s : NULL;\n\t\t}", s, soap_type(p), c_ident(p));
7122	  else if (is_wstring(p))
7123	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\twchar_t **s;\n\t\t\t*type = %s;\n\t\t\ts = soap_in_%s(soap, NULL, NULL, NULL);\n\t\t\treturn s ? *s : NULL;\n\t\t}", s, soap_type(p), c_ident(p));
7124          else
7125	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\t*type = %s;\n\t\t\treturn soap_in_%s(soap, NULL, NULL, NULL);\n\t\t}", s, soap_type(p), c_ident(p));
7126        }
7127      }
7128    }
7129  }
7130}
7131
7132void
7133in_defs3(Table *table)
7134{ int i;
7135  Tnode *p;
7136  char *s;
7137  for (i = 0; i < TYPES; i++)
7138  { for (p = Tptr[i]; p; p = p->next)
7139    { if (is_element(p) && ((!is_transient(p) && !is_template(p) && p->type != Twchar && p->type != Tfun && p->type != Tpointer && p->type != Treference && p->type != Tunion && !is_XML(p) && !is_header_or_fault(p) && !is_body(p)) || (is_string(p) && !is_XML(p))))
7140      { s = xsi_type(p);
7141	if (!*s)
7142	  s = wsdl_type(p, "");
7143	if (*s == '-')
7144	  continue;
7145	if (*s)
7146	{ if (is_dynamic_array(p) && !is_binary(p) && !has_ns(p) && !is_untyped(p))
7147	    fprintf(fout,"\n\t\tif (*soap->arrayType && !soap_match_array(soap, \"%s\"))\n\t\t{\t*type = %s;\n\t\t\treturn soap_in_%s(soap, NULL, NULL, NULL);\n\t\t}", s, soap_type(p), c_ident(p));
7148	  else if (is_string(p))
7149	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\tchar **s;\n\t\t\t*type = %s;\n\t\t\ts = soap_in_%s(soap, NULL, NULL, NULL);\n\t\t\treturn s ? *s : NULL;\n\t\t}", s, soap_type(p), c_ident(p));
7150	  else if (is_wstring(p))
7151	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\twchar_t **s;\n\t\t\t*type = %s;\n\t\t\ts = soap_in_%s(soap, NULL, NULL, NULL);\n\t\t\treturn s ? *s : NULL;\n\t\t}", s, soap_type(p), c_ident(p));
7152          else
7153	    fprintf(fout,"\n\t\tif (!soap_match_tag(soap, t, \"%s\"))\n\t\t{\t*type = %s;\n\t\t\treturn soap_in_%s(soap, NULL, NULL, NULL);\n\t\t}", s, soap_type(p), c_ident(p));
7154        }
7155      }
7156    }
7157  }
7158}
7159
7160void
7161out_defs(Table *table)
7162{ int i;
7163  char *s;
7164  Tnode *p;
7165  for (i = 0; i < TYPES; i++)
7166  { for (p = Tptr[i]; p; p = p->next)
7167    { if (is_transient(p) || is_template(p) || is_XML(p) || is_header_or_fault(p) || is_body(p))
7168        continue;
7169      if (is_element(p))
7170      { s = wsdl_type(p, "");
7171	if (*s == '-')
7172	  continue;
7173        if (p->type == Tarray)
7174          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, \"%s\", id, (%s)ptr, NULL);", soap_type(p),c_ident(p),s,c_type_id(p->ref, "(*)"));
7175        else if(p->type == Tclass && !is_external(p) && !is_volatile(p) && !is_typedef(p))
7176          fprintf(fout,"\n\tcase %s:\n\t\treturn ((%s)ptr)->soap_out(soap, \"%s\", id, NULL);", soap_type(p), c_type_id(p, "*"),s);
7177        else if (is_string(p))
7178          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_string(soap, \"%s\", id, (char*const*)&ptr, NULL);", soap_type(p),s);
7179        else if (is_wstring(p))
7180          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_wstring(soap, \"%s\", id, (wchar_t*const*)&ptr, NULL);", soap_type(p),s);
7181        else if (p->type == Tpointer)
7182          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, \"%s\", id, (%s)ptr, NULL);", soap_type(p),c_ident(p),s,c_type_id(p, "const*"));
7183        else if(p->type != Tnone && p->type != Ttemplate && p->type != Twchar && !is_void(p) && p->type != Tfun && p->type != Treference && p->type != Tunion)
7184          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, \"%s\", id, (const %s)ptr, NULL);", soap_type(p),c_ident(p),s,c_type_id(p, "*"));
7185      }
7186      else
7187      { s = xsi_type(p);
7188        if (!*s)
7189          s = wsdl_type(p, "");
7190        if (*s == '-')
7191          continue;
7192        if (p->type == Tarray)
7193          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, tag, id, (%s)ptr, \"%s\");", soap_type(p), c_ident(p),c_type_id(p->ref, "(*)"), s);
7194        else if(p->type == Tclass && !is_external(p) && !is_volatile(p) && !is_typedef(p))
7195          fprintf(fout,"\n\tcase %s:\n\t\treturn ((%s)ptr)->soap_out(soap, tag, id, \"%s\");", soap_type(p), c_type_id(p, "*"), s);
7196        else if (is_string(p))
7197          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_string(soap, tag, id, (char*const*)&ptr, \"%s\");", soap_type(p), s);
7198        else if (is_wstring(p))
7199          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_wstring(soap, tag, id, (wchar_t*const*)&ptr, \"%s\");", soap_type(p), s);
7200        else if (p->type == Tpointer)
7201          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, tag, id, (%s)ptr, \"%s\");", soap_type(p), c_ident(p),c_type_id(p, "const*"), s);
7202        else if(p->type != Tnone && p->type != Ttemplate && p->type != Twchar && !is_void(p) && p->type != Tfun && p->type != Treference && p->type != Tunion)
7203          fprintf(fout,"\n\tcase %s:\n\t\treturn soap_out_%s(soap, tag, id, (const %s)ptr, \"%s\");", soap_type(p), c_ident(p),c_type_id(p, "*"), s);
7204      }
7205    }
7206  }
7207}
7208
7209void
7210mark_defs(Table *table)
7211{ int i;
7212  Tnode *p;
7213  for (i = 0; i < TYPES; i++)
7214  { for (p = Tptr[i]; p; p = p->next)
7215    { if (is_transient(p) || is_template(p) || is_XML(p) || is_header_or_fault(p) || is_body(p) || is_void(p))
7216        continue;
7217      if (p->type == Tarray)
7218        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_%s(soap, (%s)ptr);\n\t\tbreak;", soap_type(p), c_ident(p),c_type_id(p->ref, "(*)"));
7219      else if(p->type == Tclass && !is_external(p) && !is_volatile(p) && !is_typedef(p))
7220        fprintf(fout,"\n\tcase %s:\n\t\t((%s)ptr)->soap_serialize(soap);\n\t\tbreak;", soap_type(p), c_type_id(p, "*"));
7221      else if (is_string(p))
7222        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_string(soap, (char*const*)&ptr);\n\t\tbreak;", soap_type(p));
7223      else if (is_wstring(p))
7224        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_wstring(soap, (wchar_t*const*)&ptr);\n\t\tbreak;", soap_type(p));
7225      else if (p->type == Tpointer)
7226        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_%s(soap, (%s)ptr);\n\t\tbreak;", soap_type(p), c_ident(p),c_type_id(p, "const*"));
7227      else if(p->type == Ttemplate && p->ref)
7228        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_%s(soap, (const %s)ptr);\n\t\tbreak;", soap_type(p), c_ident(p),c_type_id(p, "*"));
7229      else if(!is_primitive(p) && p->type != Tnone && p->type != Ttemplate && !is_void(p) && p->type != Tfun && p->type != Treference && p->type != Tunion)
7230        fprintf(fout,"\n\tcase %s:\n\t\tsoap_serialize_%s(soap, (const %s)ptr);\n\t\tbreak;", soap_type(p), c_ident(p),c_type_id(p, "*"));
7231    }
7232  }
7233}
7234
7235void
7236in_attach(Table *table)
7237{ int i;
7238  Tnode *p;
7239  for (i = 0; i < TYPES; i++)
7240  { for (p = Tptr[i]; p; p = p->next)
7241    { if (is_attachment(p))
7242      { if (p->type == Tclass)
7243	  fprintf(fout,"\n\t\tcase %s:\n\t\t{\t%s a;\n\t\t\ta = (%s)soap_class_id_enter(soap, soap->dime.id, NULL, %s, sizeof(%s), NULL, NULL);\n\t\t\tif (a)\n\t\t\t{\ta->__ptr = (unsigned char*)soap->dime.ptr;\n\t\t\t\ta->__size = soap->dime.size;\n\t\t\t\ta->id = (char*)soap->dime.id;\n\t\t\t\ta->type = (char*)soap->dime.type;\n\t\t\t\ta->options = (char*)soap->dime.options;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn soap->error;\n\t\t\tbreak;\n\t\t}", soap_type(p), c_type_id(p, "*"), c_type_id(p, "*"), soap_type(p), c_type(p));
7244	else
7245	  fprintf(fout,"\n\t\tcase %s:\n\t\t{\t%s a;\n\t\t\ta = (%s)soap_id_enter(soap, soap->dime.id, NULL, %s, sizeof(%s), 0, NULL, NULL, NULL);\n\t\t\tif (!a)\n\t\t\t\treturn soap->error;\n\t\t\ta->__ptr = (unsigned char*)soap->dime.ptr;\n\t\t\ta->__size = soap->dime.size;\n\t\t\ta->id = (char*)soap->dime.id;\n\t\t\ta->type = (char*)soap->dime.type;\n\t\t\ta->options = (char*)soap->dime.options;\n\t\t\tbreak;\n\t\t}", soap_type(p), c_type_id(p, "*"), c_type_id(p, "*"), soap_type(p), c_type(p));
7246      }
7247      else if (is_binary(p) && !is_transient(p))
7248      { if (p->type == Tclass)
7249	  fprintf(fout,"\n\t\tcase %s:\n\t\t{\t%s a;\n\t\t\ta = (%s)soap_class_id_enter(soap, soap->dime.id, NULL, %s, sizeof(%s), NULL, NULL);\n\t\t\tif (!a)\n\t\t\t\treturn soap->error;\n\t\t\ta->__ptr = (unsigned char*)soap->dime.ptr;\n\t\t\ta->__size = soap->dime.size;\n\t\t\tbreak;\n\t\t}", soap_type(p), c_type_id(p, "*"), c_type_id(p, "*"), soap_type(p), c_type(p));
7250	else
7251	  fprintf(fout,"\n\t\tcase %s:\n\t\t{\t%s a;\n\t\t\ta = (%s)soap_id_enter(soap, soap->dime.id, NULL, %s, sizeof(%s), 0, NULL, NULL, NULL);\n\t\t\tif (!a)\n\t\t\t\treturn soap->error;\n\t\t\ta->__ptr = (unsigned char*)soap->dime.ptr;\n\t\t\ta->__size = soap->dime.size;\n\t\t\tbreak;\n\t\t}", soap_type(p), c_type_id(p, "*"), c_type_id(p, "*"), soap_type(p), c_type(p));
7252      }
7253    }
7254  }
7255}
7256
7257void
7258soap_instantiate_class(Tnode *typ)
7259{ Table *Tptr;
7260  Entry *Eptr;
7261  int derclass = 0;
7262  char *s;
7263
7264  if (cflag)
7265    return;
7266
7267  fprintf(fhead,"\nSOAP_FMAC5 %s * SOAP_FMAC6 soap_new_%s(struct soap*, int);", c_type(typ), c_ident(typ));
7268  fprintf(fout,"\n\nSOAP_FMAC5 %s * SOAP_FMAC6 soap_new_%s(struct soap *soap, int n)\n{\treturn soap_instantiate_%s(soap, n, NULL, NULL, NULL);\n}", c_type(typ), c_ident(typ), c_ident(typ));
7269  fprintf(fhead,"\nSOAP_FMAC5 void SOAP_FMAC6 soap_delete_%s(struct soap*, %s*);", c_ident(typ), c_type(typ));
7270  fprintf(fhead,"\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_instantiate_%s(struct soap*, int, const char*, const char*, size_t*);", c_type(typ), c_ident(typ));
7271
7272  fprintf(fout,"\n\nSOAP_FMAC5 void SOAP_FMAC6 soap_delete_%s(struct soap *soap, %s)\n{\tsoap_delete(soap, p);\n}", c_ident(typ), c_type_id(typ, "*p"));
7273  fprintf(fout,"\n\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_instantiate_%s(struct soap *soap, int n, const char *type, const char *arrayType, size_t *size)", c_type(typ), c_ident(typ));
7274  fprintf(fout,"\n{");
7275  fprintf(fout, "\n\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"soap_instantiate_%s(%%d, %%s, %%s)\\n\", n, type?type:\"\", arrayType?arrayType:\"\"));", c_ident(typ));
7276
7277  fprintf(fout,"\n\tstruct soap_clist *cp = soap_link(soap, NULL, %s, n, soap_fdelete);", soap_type(typ));
7278  fprintf(fout,"\n\tif (!cp)\n\t\treturn NULL;");
7279  for (Eptr = classtable->list; Eptr; Eptr = Eptr->next)
7280  {
7281    Tptr = ((Table *) Eptr->info.typ->ref);
7282    if(Tptr == ((Table *) typ->ref)){
7283      continue;
7284    }
7285
7286    derclass = 0;
7287    while(Tptr)
7288    {
7289      if(Tptr == typ->ref){
7290	derclass = 1;
7291      }
7292
7293      Tptr = Tptr->prev;
7294    }
7295
7296    if(derclass == 1 && !is_transient(Eptr->info.typ)){
7297      if (is_dynamic_array(Eptr->info.typ) && !is_binary(Eptr->info.typ) && !has_ns(Eptr->info.typ) && !is_untyped(Eptr->info.typ))
7298        fprintf(fout,"\n\tif (arrayType && !soap_match_tag(soap, arrayType, \"%s\"))", xsi_type(Eptr->info.typ));
7299      else
7300        fprintf(fout,"\n\tif (type && !soap_match_tag(soap, type, \"%s\"))", the_type(Eptr->info.typ));
7301      fprintf(fout,"\n\t{\tcp->type = %s;", soap_type(Eptr->info.typ));
7302      fprintf(fout,"\n\t\tif (n < 0)");
7303      fprintf(fout,"\n\t\t{\tcp->ptr = (void*)new %s;", c_type(Eptr->info.typ));
7304      fprintf(fout,"\n\t\t\tif (!cp->ptr)\n\t\t\t{\tsoap->error = SOAP_EOM;\n\t\t\t\treturn NULL;\n\t\t\t}");
7305      fprintf(fout,"\n\t\t\tif (size)\n\t\t\t\t*size = sizeof(%s);", c_type(Eptr->info.typ));
7306      if ((s = has_soapref(Eptr->info.typ)))
7307        fprintf(fout,"\n\t\t\t((%s*)cp->ptr)->%s = soap;", c_type(Eptr->info.typ), s);
7308      fprintf(fout,"\n\t\t}\n\t\telse");
7309      fprintf(fout,"\n\t\t{\tcp->ptr = (void*)new %s[n];", c_type(Eptr->info.typ));
7310      fprintf(fout,"\n\t\t\tif (size)\n\t\t\t\t*size = n * sizeof(%s);", c_type(Eptr->info.typ));
7311      if (s)
7312        fprintf(fout,"\n\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t\t((%s*)cp->ptr)[i].%s = soap;", c_type(Eptr->info.typ), s);
7313      fprintf(fout,"\n\t\t}");
7314      fprintf(fout,"\n\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Instantiated location=%%p\\n\", cp->ptr));");
7315      fprintf(fout,"\n\t\treturn (%s*)cp->ptr;", c_type(Eptr->info.typ));
7316      fprintf(fout,"\n\t}");
7317
7318      derclass = 0;
7319    }
7320  }
7321
7322  fprintf(fout,"\n\tif (n < 0)");
7323  fprintf(fout,"\n\t{\tcp->ptr = (void*)new %s;", c_type(typ));
7324  fprintf(fout,"\n\t\tif (size)\n\t\t\t*size = sizeof(%s);", c_type(typ));
7325  if ((s = has_soapref(typ)))
7326    fprintf(fout,"\n\t\t((%s*)cp->ptr)->%s = soap;", c_type(typ), s);
7327  fprintf(fout,"\n\t}\n\telse");
7328  fprintf(fout,"\n\t{\tcp->ptr = (void*)new %s[n];", c_type(typ));
7329  fprintf(fout,"\n\t\tif (!cp->ptr)\n\t\t{\tsoap->error = SOAP_EOM;\n\t\t\treturn NULL;\n\t\t}");
7330  fprintf(fout,"\n\t\tif (size)\n\t\t\t*size = n * sizeof(%s);", c_type(typ));
7331  if (s)
7332    fprintf(fout,"\n\t\tfor (int i = 0; i < n; i++)\n\t\t\t((%s*)cp->ptr)[i].%s = soap;", c_type(typ), s);
7333  fprintf(fout,"\n\t}");
7334  fprintf(fout,"\n\t\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Instantiated location=%%p\\n\", cp->ptr));");
7335  fprintf(fout,"\n\treturn (%s*)cp->ptr;", c_type(typ));
7336
7337  fprintf(fout,"\n}");
7338
7339  /* extern "C" causes C++ namespace linking issues */
7340  /* fprintf(fhead,"\n#ifdef __cplusplus\nextern \"C\" {\n#endif"); */
7341  fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_copy_%s(struct soap*, int, int, void*, size_t, const void*, size_t);", c_ident(typ));
7342  /* fprintf(fhead,"\n#ifdef __cplusplus\n}\n#endif"); */
7343  /* fprintf(fout,"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif"); */
7344  fprintf(fout,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_copy_%s(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)", c_ident(typ));
7345  fprintf(fout,"\n{");
7346  fprintf(fout,"\n\tDBGLOG(TEST, SOAP_MESSAGE(fdebug, \"Copying %s %%p -> %%p\\n\", q, p));", c_type(typ));
7347  fprintf(fout,"\n\t*(%s*)p = *(%s*)q;\n}", c_type(typ), c_type(typ));
7348  /* fprintf(fout,"\n#ifdef __cplusplus\n}\n#endif"); */
7349}
7350
7351int
7352get_dimension(Tnode *typ)
7353{ if (((Tnode*)typ->ref)->width)
7354    return typ->width / ((Tnode*) typ->ref)->width;
7355  return 0;
7356}
7357
7358
7359void
7360mark(Tnode *typ)
7361{ int d;
7362  Table *table,*t;
7363  Entry *p;
7364  Tnode* temp;
7365  int cardinality;
7366
7367  if (is_primitive(typ))
7368    return;
7369
7370  if (is_typedef(typ))
7371  { fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "const*"));
7372    if (typ->type == Tclass && !is_stdstring(typ) && !is_stdwstring(typ) && !is_volatile(typ))
7373      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)\n{\ta->soap_serialize(soap);\n}",c_ident(typ),c_type_id(typ, "const*a"));
7374    else
7375      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)\n{\tsoap_serialize_%s(soap, a);\n}",c_ident(typ),c_type_id(typ, "const*a"),t_ident(typ));
7376    return;
7377  }
7378
7379  if ((p = is_dynamic_array(typ)))
7380  { if (typ->type == Tclass && !is_volatile(typ))
7381    { if (is_external(typ))
7382          return;
7383        fprintf(fout,"\n\nvoid %s::soap_serialize(struct soap *soap) const\n{",c_ident(typ));
7384        if (is_binary(typ))
7385	{ if (is_attachment(typ))
7386          { fprintf(fout,"\n\tif (this->__ptr && !soap_array_reference(soap, this, (struct soap_array*)&this->__ptr, 1, %s))", soap_type(typ));
7387            fprintf(fout,"\n\t\tif (this->id || this->type)\n\t\t\tsoap->mode |= SOAP_ENC_DIME;\n}");
7388	  }
7389          else
7390            fprintf(fout,"\n\tif (this->__ptr)\n\t\tsoap_array_reference(soap, this, (struct soap_array*)&this->%s, 1, %s);\n}", ident(p->sym->name), soap_type(typ));
7391      fflush(fout);
7392      return;
7393	}
7394	else
7395	{
7396      if (is_XML(p->info.typ->ref))
7397      { fprintf(fout,"\n}");
7398        return;
7399      }
7400      d = get_Darraydims(typ);
7401      if (d)
7402      { fprintf(fout,"\n\tif (this->%s && !soap_array_reference(soap, this, (struct soap_array*)&this->%s, %d, %s))", ident(p->sym->name), ident(p->sym->name), d, soap_type(typ));
7403        fprintf(fout,"\n\t\tfor (int i = 0; i < soap_size(this->__size, %d); i++)", d);
7404      }
7405      else
7406      { fprintf(fout,"\n\tif (this->%s && !soap_array_reference(soap, this, (struct soap_array*)&this->%s, 1, %s))", ident(p->sym->name), ident(p->sym->name), soap_type(typ));
7407        fprintf(fout,"\n\t\tfor (int i = 0; i < this->__size; i++)");
7408      }
7409      fprintf(fout,"\n\t\t{");
7410      if (has_ptr(p->info.typ->ref))
7411        fprintf(fout,"\tsoap_embedded(soap, this->%s + i, %s);", ident(p->sym->name), soap_type(p->info.typ->ref));
7412      if (((Tnode*)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
7413        fprintf(fout,"\n\t\t\tthis->%s[i].soap_serialize(soap);", ident(p->sym->name));
7414      else if (!is_primitive(p->info.typ->ref))
7415        fprintf(fout,"\n\t\t\tsoap_serialize_%s(soap, this->%s + i);", c_ident(p->info.typ->ref), ident(p->sym->name));
7416      fprintf(fout,"\n\t\t}\n}");
7417      return;
7418      }
7419    }
7420    else
7421    { if (is_external(typ))
7422        { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "const*"));
7423          return;
7424	}
7425        fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "const*"));
7426        fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)\n{",c_ident(typ),c_type_id(typ, "const*a"));
7427        if (is_binary(typ))
7428	{ if (is_attachment(typ))
7429          { fprintf(fout,"\n\tif (a->__ptr && !soap_array_reference(soap, a, (struct soap_array*)&a->__ptr, 1, %s))", soap_type(typ));
7430            fprintf(fout,"\n\t\tif (a->id || a->type)\n\t\t\tsoap->mode |= SOAP_ENC_DIME;\n}");
7431	  }
7432          else
7433            fprintf(fout,"\n\tif (a->__ptr)\n\t\tsoap_array_reference(soap, a, (struct soap_array*)&a->%s, 1, %s);\n}", ident(p->sym->name), soap_type(typ));
7434      fflush(fout);
7435      return;
7436	}
7437	else
7438	{
7439      if (is_XML(p->info.typ->ref))
7440      { fprintf(fout,"\n}");
7441        return;
7442      }
7443      fprintf(fout,"\n\tint i;");
7444      d = get_Darraydims(typ);
7445      if (d)
7446      { fprintf(fout,"\n\tif (a->%s && !soap_array_reference(soap, a, (struct soap_array*)&a->%s, %d, %s))", ident(p->sym->name), ident(p->sym->name), d, soap_type(typ));
7447        fprintf(fout,"\n\t\tfor (i = 0; i < soap_size(a->__size, %d); i++)", d);
7448      }
7449      else
7450      { fprintf(fout,"\n\tif (a->%s && !soap_array_reference(soap, a, (struct soap_array*)&a->%s, 1, %s))", ident(p->sym->name), ident(p->sym->name), soap_type(typ));
7451        fprintf(fout,"\n\t\tfor (i = 0; i < a->__size; i++)");
7452      }
7453      fprintf(fout,"\n\t\t{");
7454      if (has_ptr(p->info.typ->ref))
7455        fprintf(fout,"\tsoap_embedded(soap, a->%s + i, %s);", ident(p->sym->name), soap_type(p->info.typ->ref));
7456      if (((Tnode*)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
7457        fprintf(fout,"\n\t\t\ta->%s[i].soap_serialize(soap);", ident(p->sym->name));
7458      else if (!is_primitive(p->info.typ->ref))
7459        fprintf(fout,"\n\t\t\tsoap_serialize_%s(soap, a->%s + i);", c_ident(p->info.typ->ref), ident(p->sym->name));
7460      fprintf(fout,"\n\t\t}\n}");
7461      fflush(fout);
7462      return;
7463      }
7464    }
7465  }
7466  if (is_stdstring(typ) || is_stdwstring(typ))
7467  { fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7468    fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, const %s)\n{\t(void)soap; (void)p; /* appease -Wall -Werror */\n}",c_ident(typ),c_type_id(typ, "*p"));
7469    return;
7470  }
7471  switch(typ->type)
7472  {
7473    case Tclass:
7474      if (!is_volatile(typ))
7475      {
7476      if (is_external(typ))
7477      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7478        return;
7479      }
7480      table=(Table*)typ->ref;
7481      fprintf(fout,"\n\nvoid %s::soap_serialize(struct soap *soap) const\n{", ident(typ->id->name));
7482      fprintf(fout, "\n\t(void)soap; /* appease -Wall -Werror */");
7483      for (t = table; t != (Table *) 0; t = t->prev)
7484      {
7485	for (p = t->list; p != (Entry*) 0; p = p->next) {
7486	  if (p->info.sto & (Sconst | Sprivate | Sprotected))
7487	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
7488	  else if (is_transient(p->info.typ))
7489	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
7490	  else if (p->info.sto & Sattribute)
7491	    ;
7492	  else if (is_repetition(p))
7493	  {
7494      if (!is_XML(p->next->info.typ)) {
7495      fprintf(fout,"\n\tif (this->%s::%s)", ident(t->sym->name), ident(p->next->sym->name));
7496      fprintf(fout,"\n\t{\tint i;\n\t\tfor (i = 0; i < this->%s::%s; i++)\n\t\t{", ident(t->sym->name), ident(p->sym->name));
7497      if (!is_invisible(p->next->sym->name))
7498        if (has_ptr(p->next->info.typ->ref))
7499          fprintf(fout,"\n\t\t\tsoap_embedded(soap, this->%s::%s + i, %s);", ident(t->sym->name), ident(p->next->sym->name), soap_type(p->next->info.typ->ref));
7500      if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
7501        fprintf(fout,"\n\t\t\tthis->%s::%s[i].soap_serialize(soap);", ident(t->sym->name), ident(p->next->sym->name));
7502      else if (!is_primitive(p->next->info.typ->ref))
7503        fprintf(fout,"\n\t\t\tsoap_serialize_%s(soap, this->%s::%s + i);", c_ident(p->next->info.typ->ref), ident(t->sym->name), ident(p->next->sym->name));
7504      fprintf(fout,"\n\t\t}\n\t}");
7505	  }
7506          p = p->next;
7507	  }
7508	  else if (is_anytype(p))
7509	  { fprintf(fout,"\n\tsoap_markelement(soap, this->%s, this->%s);", ident(p->next->sym->name), ident(p->sym->name));
7510            p = p->next;
7511	  }
7512	  else if (is_choice(p))
7513	  { fprintf(fout,"\n\tsoap_serialize_%s(soap, this->%s::%s, &this->%s::%s);", c_ident(p->next->info.typ), ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name));
7514            p = p->next;
7515	  }
7516	  else if(p->info.typ->type==Tarray)
7517	    {
7518              if (has_ptr(p->info.typ))
7519	        fprintf(fout,"\n\tsoap_embedded(soap, this->%s::%s, %s);", ident(t->sym->name), ident(p->sym->name), soap_type(p->info.typ));
7520	      fprintf(fout,"\n\tsoap_serialize_%s(soap, this->%s::%s);", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name));
7521	    }
7522	  else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
7523	    {
7524              if (has_ptr(p->info.typ))
7525	        fprintf(fout,"\n\tsoap_embedded(soap, &this->%s::%s, %s);", ident(t->sym->name), ident(p->sym->name), soap_type(p->info.typ));
7526	      fprintf(fout,"\n\tthis->%s::%s.soap_serialize(soap);", ident(t->sym->name), ident(p->sym->name));
7527	    }
7528	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
7529	  {
7530	    if (!is_template(p->info.typ))
7531              if (has_ptr(p->info.typ))
7532	        fprintf(fout,"\n\tsoap_embedded(soap, &this->%s::%s, %s);", ident(t->sym->name), ident(p->sym->name), soap_type(p->info.typ));
7533	    if (!is_primitive(p->info.typ))
7534	      fprintf(fout,"\n\tsoap_serialize_%s(soap, &this->%s::%s);", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name));
7535	  }
7536	}
7537      }
7538      fprintf(fout,"\n}");
7539      break;
7540      }
7541    case Tstruct:
7542
7543      if (is_external(typ) && !is_volatile(typ))
7544      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7545        return;
7546      }
7547      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7548      if (!typ->ref)
7549        return;
7550      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, const %s)\n{",c_ident(typ),c_type_id(typ, "*a"));
7551      /* DYNAMIC ARRAY */
7552
7553      fprintf(fout, "\n\t(void)soap; (void)a; /* appease -Wall -Werror */");
7554      table=(Table*)typ->ref;
7555      for (t = table; t != (Table *) 0; t = t->prev) {
7556	for (p = t->list; p != (Entry*) 0; p = p->next) {
7557	  if (p->info.sto & (Sconst | Sprivate | Sprotected))
7558	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
7559	  else if (is_transient(p->info.typ))
7560	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
7561	  else if (p->info.sto & Sattribute)
7562	    ;
7563	  else if (is_repetition(p))
7564	  {
7565      if (!is_XML(p->next->info.typ)) {
7566      fprintf(fout,"\n\tif (a->%s)", ident(p->next->sym->name));
7567      fprintf(fout,"\n\t{\tint i;\n\t\tfor (i = 0; i < a->%s; i++)\n\t\t{", ident(p->sym->name));
7568      if (!is_invisible(p->next->sym->name))
7569        if (has_ptr(p->next->info.typ->ref))
7570          fprintf(fout,"\n\t\t\tsoap_embedded(soap, a->%s + i, %s);", ident(p->next->sym->name), soap_type(p->next->info.typ->ref));
7571      if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
7572        fprintf(fout,"\n\t\t\ta->%s[i].soap_serialize(soap);", ident(p->next->sym->name));
7573      else if (!is_primitive(p->next->info.typ->ref))
7574        fprintf(fout,"\n\t\t\tsoap_serialize_%s(soap, a->%s + i);", c_ident(p->next->info.typ->ref), ident(p->next->sym->name));
7575      fprintf(fout,"\n\t\t}\n\t}");
7576	  }
7577          p = p->next;
7578	  }
7579	  else if (is_anytype(p))
7580	  { fprintf(fout,"\n\tsoap_markelement(soap, a->%s, a->%s);", ident(p->next->sym->name), ident(p->sym->name));
7581            p = p->next;
7582	  }
7583	  else if (is_choice(p))
7584	  { fprintf(fout,"\n\tsoap_serialize_%s(soap, a->%s, &a->%s);", c_ident(p->next->info.typ), ident(p->sym->name), ident(p->next->sym->name));
7585            p = p->next;
7586	  }
7587	  else if(p->info.typ->type==Tarray)
7588	    {
7589              if (has_ptr(p->info.typ))
7590	        fprintf(fout,"\n\tsoap_embedded(soap, a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7591	      fprintf(fout,"\n\tsoap_serialize_%s(soap, a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7592	    }
7593	  else if(p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
7594	    {
7595              if (has_ptr(p->info.typ))
7596	        fprintf(fout,"\n\tsoap_embedded(soap, &a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7597	      fprintf(fout,"\n\ta->%s.soap_serialize(soap);", ident(p->sym->name));
7598	    }
7599	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
7600	    {
7601	      if (!is_template(p->info.typ))
7602                if (has_ptr(p->info.typ))
7603	          fprintf(fout,"\n\tsoap_embedded(soap, &a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7604	      if (!is_primitive(p->info.typ))
7605	        fprintf(fout,"\n\tsoap_serialize_%s(soap, &a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7606	    }
7607	}
7608      }
7609      fprintf(fout,"\n}");
7610      break;
7611
7612    case Tunion:
7613      if (is_external(typ) && !is_volatile(typ))
7614      { fprintf(fhead, "\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, int, const %s);", c_ident(typ), c_type_id(typ, "*"));
7615        return;
7616      }
7617      table=(Table*)typ->ref;
7618      fprintf(fhead, "\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, int, const %s);", c_ident(typ), c_type_id(typ, "*"));
7619      fprintf(fout, "\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, int choice, const %s)\n{", c_ident(typ), c_type_id(typ, "*a"));
7620      fprintf(fout, "\n\t(void)soap; (void)a; /* appease -Wall -Werror */");
7621      fprintf(fout, "\n\tswitch (choice)\n\t{");
7622      for (t = table; t; t = t->prev)
7623      { for (p = t->list; p; p = p->next)
7624	{ if (p->info.sto & (Sconst | Sprivate | Sprotected))
7625	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
7626	  else if (is_transient(p->info.typ))
7627	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
7628	  else if (p->info.sto & Sattribute)
7629	    ;
7630	  else if (is_repetition(p))
7631	    ;
7632	  else if (is_anytype(p))
7633	    ;
7634	  else if (p->info.typ->type==Tarray)
7635	    {
7636	      fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
7637              if (has_ptr(p->info.typ))
7638	        fprintf(fout,"\n\t\tsoap_embedded(soap, a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7639	      fprintf(fout,"\n\t\tsoap_serialize_%s(soap, a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7640	      fprintf(fout, "\n\t\tbreak;");
7641	    }
7642	  else if(p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
7643	    {
7644	      fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
7645              if (has_ptr(p->info.typ))
7646	        fprintf(fout,"\n\t\tsoap_embedded(soap, &a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7647	      fprintf(fout,"\n\t\ta->%s.soap_serialize(soap);", ident(p->sym->name));
7648	      fprintf(fout, "\n\t\tbreak;");
7649	    }
7650	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_XML(p->info.typ))
7651	    {
7652	      fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
7653              if (has_ptr(p->info.typ))
7654	        fprintf(fout,"\n\t\tsoap_embedded(soap, &a->%s, %s);", ident(p->sym->name), soap_type(p->info.typ));
7655	      if (!is_primitive(p->info.typ))
7656	        fprintf(fout,"\n\t\tsoap_serialize_%s(soap, &a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7657	      fprintf(fout, "\n\t\tbreak;");
7658	    }
7659	}
7660      }
7661      fprintf(fout,"\n\tdefault:\n\t\tbreak;\n\t}\n}");
7662      break;
7663    case Tpointer:
7664      if (((Tnode*)typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref) && !is_typedef(typ->ref))
7665      { if (is_external(typ))
7666        { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const*"));
7667          return;
7668	}
7669        fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const*"));
7670	fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)\n{", c_ident(typ),c_type_id(typ, "const*a"));
7671	p = is_dynamic_array(typ->ref);
7672	if (p)
7673        { d = get_Darraydims(typ->ref);
7674          if (d)
7675	    fprintf(fout,"\n\tif (*a)");
7676	  else
7677	    fprintf(fout,"\n\tif (*a)");
7678	}
7679	else
7680	  fprintf(fout,"\n\tif (!soap_reference(soap, *a, %s))", soap_type(typ->ref));
7681	fprintf(fout,"\n\t\t(*a)->soap_serialize(soap);\n}");
7682	break;
7683      }
7684      else
7685      {
7686        if (is_external(typ))
7687	{ fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const*"));
7688          return;
7689	}
7690	fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const*"));
7691	fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)\n{", c_ident(typ),c_type_id(typ, "const*a"));
7692	if (is_string(typ) || is_wstring(typ))
7693	  fprintf(fout,"\n\tsoap_reference(soap, *a, %s);\n}", soap_type(typ));
7694	else if (is_primitive(typ->ref))
7695	  fprintf(fout,"\n\tsoap_reference(soap, *a, %s);\n}", soap_type(typ->ref));
7696	else if ((p = is_dynamic_array(typ->ref)) != NULL)
7697        { d = get_Darraydims(typ->ref);
7698          if (d)
7699	    fprintf(fout,"\n\tif (*a)");
7700	  else
7701	    fprintf(fout,"\n\tif (*a)");
7702	  fprintf(fout,"\n\t\tsoap_serialize_%s(soap, *a);\n}", c_ident(typ->ref));
7703	}
7704	else
7705	{ fprintf(fout,"\n\tif (!soap_reference(soap, *a, %s))", soap_type(typ->ref));
7706	  fprintf(fout,"\n\t\tsoap_serialize_%s(soap, *a);\n}", c_ident(typ->ref));
7707	}
7708	break;
7709      }
7710    case Tarray:
7711      if (is_external(typ))
7712      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const"));
7713        return;
7714      }
7715      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, %s);", c_ident(typ),c_type_id(typ, "const"));
7716      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, %s)", c_ident(typ),c_type_id(typ, "const a"));
7717      if (is_primitive(typ->ref))
7718      { fprintf(fout, "\n{");
7719        fprintf(fout, "\n\t(void)soap; (void)a; /* appease -Wall -Werror */");
7720      }
7721      else
7722      { fprintf(fout,"\n{\tint i;");
7723        fprintf(fout,"\n\tfor(i = 0; i < %d; i++)", get_dimension(typ));
7724
7725        temp=typ->ref;;
7726        cardinality = 1;
7727        while(temp->type==Tarray)
7728	{
7729	  temp=temp->ref;
7730	  cardinality++;
7731	}
7732        fprintf(fout,"\n\t{");
7733        if (has_ptr(typ->ref))
7734	{
7735          fprintf(fout,"\tsoap_embedded(soap, a");
7736          if(cardinality > 1)
7737	    fprintf(fout,"[i]");
7738          else
7739	    fprintf(fout,"+i");
7740          fprintf(fout,", %s);", soap_type(typ->ref));
7741        }
7742	if (((Tnode *)typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref) && !is_typedef(typ->ref))
7743      	{	fprintf(fout,"\n\ta[i].soap_serialize(soap)");
7744	}
7745	else if (!is_primitive(typ->ref))
7746      	{	fprintf(fout,"\n\tsoap_serialize_%s(soap, a",c_ident(typ->ref));
7747      		if(cardinality > 1){
7748		fprintf(fout,"[i])");
7749      		}else {
7750	  	fprintf(fout,"+i)");
7751      		}
7752	}
7753        fprintf(fout,";\n\t}");
7754      }
7755      fprintf(fout,"\n}");
7756      break;
7757    case Ttemplate:
7758      if (is_external(typ))
7759      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7760        return;
7761      }
7762      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap*, const %s);",c_ident(typ),c_type_id(typ, "*"));
7763      temp = typ->ref;
7764      if (!temp)
7765        return;
7766      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_serialize_%s(struct soap *soap, const %s)\n{",c_ident(typ),c_type_id(typ, "*a"));
7767      if (!is_primitive(temp) && !is_XML(temp) && temp->type != Tfun && !is_void(temp))
7768      { fprintf(fout, "\n\tfor (%s::const_iterator i = a->begin(); i != a->end(); ++i)", c_type(typ));
7769        if (temp->type==Tclass && !is_external(temp) && !is_volatile(temp) && !is_typedef(temp))
7770	  fprintf(fout,"\n\t\t(*i).soap_serialize(soap);");
7771        else
7772          fprintf(fout,"\n\t\tsoap_serialize_%s(soap, &(*i));", c_ident(temp));
7773      }
7774      fprintf(fout, "\n}");
7775    default:     break;
7776    }
7777}
7778
7779void
7780defaults(typ)
7781Tnode* typ;
7782{ int i, d;
7783  Table *table,*t;
7784  Entry *p;
7785  Tnode *temp;
7786  char *s;
7787  int cardinality;
7788
7789  if (typ->type == Tpointer && !is_string(typ))
7790    return;
7791
7792  if (is_typedef(typ))
7793  { fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7794    if (typ->type == Tclass && !is_stdstring(typ) && !is_stdwstring(typ) && !is_volatile(typ))
7795      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{\ta->%s::soap_default(soap);\n}",c_ident(typ),c_type_id(typ, "*a"),t_ident(typ));
7796    else
7797      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{\tsoap_default_%s(soap, a);\n}",c_ident(typ),c_type_id(typ, "*a"),t_ident(typ));
7798    return;
7799  }
7800  p = is_dynamic_array(typ);
7801  if (p)
7802  { if (typ->type == Tclass && !is_volatile(typ))
7803    { if (is_external(typ))
7804        return;
7805        fprintf(fout,"\n\nvoid %s::soap_default(struct soap *soap)\n{", c_ident(typ));
7806        if ((s = has_soapref(typ)))
7807          fprintf(fout,"\n\tthis->%s = soap;", s);
7808	d = get_Darraydims(typ);
7809        if (d)
7810	{ fprintf(fout,"\n\tthis->%s = NULL;", ident(p->sym->name));
7811	  for (i = 0; i < d; i++)
7812	  { fprintf(fout,"\n\tthis->__size[%d] = 0;", i);
7813            if (has_offset(typ) && (((Table*)typ->ref)->list->next->next->info.sto & Sconst) == 0)
7814              fprintf(fout, "\n\tthis->__offset[%d] = 0;", i);
7815	  }
7816	}
7817	else
7818	{ fprintf(fout,"\n\tthis->__size = 0;\n\tthis->%s = NULL;", ident(p->sym->name));
7819          if (has_offset(typ) && (((Table*)typ->ref)->list->next->next->info.sto & Sconst) == 0)
7820            fprintf(fout, "\n\tthis->__offset = 0;");
7821	}
7822	if (is_attachment(typ))
7823          fprintf(fout,"\n\tthis->id = NULL;\n\tthis->type = NULL;\n\tthis->options = NULL;");
7824        fprintf(fout,"\n}");
7825      }
7826      else
7827      { if (is_external(typ))
7828        { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7829          return;
7830	}
7831        fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7832        fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{", c_ident(typ),c_type_id(typ, "*a"));
7833        if ((s = has_soapref(typ)))
7834          fprintf(fout,"\n\ta->%s = soap;", s);
7835	d = get_Darraydims(typ);
7836        if (d)
7837	{ fprintf(fout,"\n\ta->%s = NULL;", ident(p->sym->name));
7838	  for (i = 0; i < d; i++)
7839	  { fprintf(fout,"\n\ta->__size[%d] = 0;", i);
7840            if (has_offset(typ) && (((Table*)typ->ref)->list->next->next->info.sto & Sconst) == 0)
7841              fprintf(fout, "\n\ta->__offset[%d] = 0;", i);
7842	  }
7843	}
7844	else
7845	{ fprintf(fout,"\n\ta->__size = 0;\n\ta->%s = NULL;", ident(p->sym->name));
7846          if (has_offset(typ) && (((Table*)typ->ref)->list->next->next->info.sto & Sconst) == 0)
7847            fprintf(fout, "\n\ta->__offset = 0;");
7848	}
7849	if (is_attachment(typ))
7850          fprintf(fout,"\n\ta->id = NULL;\n\ta->type = NULL;\n\ta->options = NULL;");
7851        fprintf(fout,"\n}");
7852      }
7853      fflush(fout);
7854      return;
7855  }
7856  if (is_primitive(typ) || is_string(typ))
7857  {   if (is_external(typ))
7858      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7859        return;
7860      }
7861      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7862      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{\t(void)soap; /* appease -Wall -Werror */\n#ifdef SOAP_DEFAULT_%s\n\t*a = SOAP_DEFAULT_%s;\n#else\n\t*a = (%s)0;\n#endif\n}",c_ident(typ),c_type_id(typ, "*a"), c_ident(typ), c_ident(typ), c_type(typ));
7863      return;
7864  }
7865  if (is_stdstring(typ) || is_stdwstring(typ))
7866  { fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7867    fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{\t(void)soap; /* appease -Wall -Werror */\n\tp->erase();\n}",c_ident(typ),c_type_id(typ, "*p"));
7868    return;
7869  }
7870  switch(typ->type)
7871    {
7872    case Tclass:
7873      /* CLASS */
7874      if (!is_volatile(typ))
7875      {
7876      if (is_external(typ))
7877      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7878        return;
7879      }
7880      table=(Table*)typ->ref;
7881      fprintf(fout,"\n\nvoid %s::soap_default(struct soap *soap)\n{", ident(typ->id->name));
7882      if ((s = has_soapref(typ)))
7883        fprintf(fout,"\n\tthis->%s = soap;", s);
7884      else
7885        fprintf(fout, "\n\t(void)soap; /* appease -Wall -Werror */");
7886
7887      fflush(fout);
7888      for (t = table; t != (Table *) 0; t = t->prev)
7889      { for (p = t->list; p != (Entry*) 0; p = p->next)
7890	  if (p->info.sto & Sconst)
7891	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
7892	  else if (is_transient(p->info.typ))
7893	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
7894	  else if (is_choice(p))
7895	  { fprintf(fout, "\n\tthis->%s::%s = 0;", ident(t->sym->name), ident(p->sym->name));
7896	    p = p->next;
7897	  }
7898	  else if (is_repetition(p) || is_anytype(p))
7899	  { fprintf(fout, "\n\tthis->%s::%s = 0;\n\tthis->%s::%s = NULL;", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name));
7900	    p = p->next;
7901	  }
7902	  else
7903	  {
7904	  if(p->info.typ->type==Tarray){
7905	    fprintf(fout,"\n\tsoap_default_%s(soap, this->%s::%s);", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name));
7906	  }
7907	  else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
7908	    fprintf(fout,"\n\tthis->%s::%s.%s::soap_default(soap);", ident(t->sym->name), ident(p->sym->name), c_ident(p->info.typ));
7909	  else if (p->info.hasval)
7910	  { if (p->info.typ->type == Tpointer && is_stdstring(p->info.typ->ref))
7911	      fprintf(fout,"\n\tstatic std::string soap_tmp_%s(\"%s\");\n\tthis->%s::%s = &soap_tmp_%s;", ident(p->sym->name), p->info.val.s, ident(t->sym->name), ident(p->sym->name), ident(p->sym->name));
7912	    else
7913	      fprintf(fout,"\n\tthis->%s::%s%s;", ident(t->sym->name), ident(p->sym->name), c_init(p));
7914	  }
7915	  else if (p->info.typ->type == Tpointer && (!is_string(p->info.typ) || is_XML(p->info.typ)))
7916	    fprintf(fout,"\n\tthis->%s::%s = NULL;", ident(t->sym->name), ident(p->sym->name));
7917	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
7918	    fprintf(fout,"\n\tsoap_default_%s(soap, &this->%s::%s);", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name));
7919	  }
7920	}
7921      }
7922      fprintf(fout,"\n}");
7923      fflush(fout);
7924      break;
7925      }
7926
7927    case Tstruct:
7928      table=(Table*)typ->ref;
7929
7930      if (is_external(typ) && !is_volatile(typ))
7931      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7932        return;
7933      }
7934      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
7935      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{", c_ident(typ),c_type_id(typ, "*a"));
7936      fflush(fout);
7937      if ((s = has_soapref(typ)))
7938        fprintf(fout,"\n\ta->%s = soap;", s);
7939      else
7940        fprintf(fout, "\n\t(void)soap; (void)a; /* appease -Wall -Werror */");
7941      for (t = table; t != (Table *) 0; t = t->prev)
7942      { for (p = t->list; p != (Entry*) 0; p = p->next)
7943	  if (p->info.sto & (Sconst | Sprivate | Sprotected))
7944	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
7945	  else if (is_transient(p->info.typ))
7946	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
7947	  else if (is_choice(p))
7948	  { fprintf(fout, "\n\ta->%s = 0;", ident(p->sym->name));
7949	    p = p->next;
7950	  }
7951	  else if (is_repetition(p) || is_anytype(p))
7952	  { fprintf(fout, "\n\ta->%s = 0;\n\ta->%s = NULL;", ident(p->sym->name), ident(p->next->sym->name));
7953	    p = p->next;
7954	  }
7955	  else
7956	  {
7957	  if (p->info.typ->type==Tarray)
7958	    fprintf(fout,"\n\tsoap_default_%s(soap, a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7959	  else if (p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
7960	    fprintf(fout,"\n\ta->%s.%s::soap_default(soap);", ident(p->sym->name), c_ident(p->info.typ));
7961	  else if (p->info.hasval)
7962	  { if (p->info.typ->type == Tpointer && is_stdstring(p->info.typ->ref))
7963	      fprintf(fout,"\n\tstatic std::string soap_tmp_%s(\"%s\");\n\ta->%s = &soap_tmp_%s;", ident(p->sym->name), p->info.val.s, ident(p->sym->name), ident(p->sym->name));
7964	    else
7965	      fprintf(fout,"\n\ta->%s%s;", ident(p->sym->name), c_init(p));
7966	  }
7967	  else if (p->info.typ->type == Tpointer && (!is_string(p->info.typ) || is_XML(p->info.typ)))
7968	    fprintf(fout,"\n\ta->%s = NULL;", ident(p->sym->name));
7969	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
7970	    fprintf(fout,"\n\tsoap_default_%s(soap, &a->%s);", c_ident(p->info.typ), ident(p->sym->name));
7971	}
7972      }
7973      fprintf(fout,"\n}");
7974      fflush(fout);
7975      break;
7976    case Tarray:
7977      if (is_external(typ))
7978      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type(typ));
7979        return;
7980      }
7981      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type(typ));
7982      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{", c_ident(typ),c_type_id(typ, "a"));
7983      fprintf(fout,"\n\tint i;");
7984      fprintf(fout,"\n\t(void)soap; /* appease -Wall -Werror */");
7985      fprintf(fout,"\n\tfor (i = 0; i < %d; i++)",get_dimension(typ));
7986      temp = typ->ref;
7987      cardinality = 1;
7988      while(temp->type==Tarray)
7989      {
7990	  temp=temp->ref;
7991	  cardinality++;
7992      }
7993      if (((Tnode *)typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref))
7994      {
7995      	if (cardinality>1)
7996		fprintf(fout,"a[i].%s::soap_default(soap)", t_ident(typ->ref));
7997     	else
7998		fprintf(fout,"(a+i)->soap_default(soap)");
7999      }
8000      else if (((Tnode*)typ->ref)->type == Tpointer)
8001      	fprintf(fout,"\n\ta[i] = NULL");
8002      else
8003      {
8004      	fprintf(fout,"\n\tsoap_default_%s(soap, a",c_ident(typ->ref));
8005      	if (cardinality>1)
8006		fprintf(fout,"[i])");
8007     	 else
8008		fprintf(fout,"+i)");
8009      }
8010      fprintf(fout,";\n}");
8011      break;
8012
8013    case Ttemplate:
8014      if (is_external(typ))
8015      { fprintf(fhead,"\nSOAP_FMAC1 void SOAP_FMAC2 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
8016        return;
8017      }
8018      fprintf(fhead,"\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap*, %s);",c_ident(typ),c_type_id(typ, "*"));
8019      fprintf(fout,"\n\nSOAP_FMAC3 void SOAP_FMAC4 soap_default_%s(struct soap *soap, %s)\n{",c_ident(typ),c_type_id(typ, "*p"));
8020      fprintf(fout,"\n\tp->clear();");
8021      fprintf(fout,"\n}");
8022      fflush(fout);
8023      break;
8024    default    :break;
8025    }
8026
8027}
8028
8029void
8030soap_put(Tnode *typ)
8031{ int d;
8032  Entry *p;
8033  char *ci = c_ident(typ);
8034  char *ct = c_type(typ);
8035  char *ctp = c_type_id(typ, "*");
8036  char *ctpa = c_type_id(typ, "*a");
8037  char *ctc = c_type_id(typ, "const");
8038  char *ctca = c_type_id(typ, "const a");
8039  char *ctcp = c_type_id(typ, "const*");
8040  char *ctcpa = c_type_id(typ, "const*a");
8041
8042  if (typ->type == Ttemplate || typ->type == Tunion)
8043    return;
8044
8045  if (typ->type == Tarray)
8046  { fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap*, %s, const char*, const char*);", ci,ctc);
8047    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap *soap, %s, const char *tag, const char *type)\n{", ci,ctca);
8048  }
8049  else if (typ->type == Tclass && !is_external(typ) && !is_volatile(typ) && !is_typedef(typ))
8050    fprintf(fout,"\n\nint %s::soap_put(struct soap *soap, const char *tag, const  char *type) const\n{", ct);
8051  else if (typ->type == Tpointer)
8052  { fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap*, %s, const char*, const char*);", ci,ctcp);
8053    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap *soap, %s, const char *tag, const char *type)\n{", ci,ctcpa);
8054  }
8055  else
8056  { fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap*, const %s, const char*, const char*);", ci,ctp);
8057    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_put_%s(struct soap *soap, const %s, const char *tag, const char *type)\n{", ci,ctpa);
8058  }
8059  fflush(fout);
8060    fprintf(fout,"\n\tregister int id = ");
8061    if (is_invisible(typ->id->name))
8062      fprintf(fout,"0;");
8063    else if ((p = is_dynamic_array(typ)) != NULL)
8064    { d = get_Darraydims(typ);
8065      if (typ->type == Tclass && !is_volatile(typ) && !is_typedef(typ))
8066      { if (d)
8067          fprintf(fout,"soap_embed(soap, (void*)this, (struct soap_array*)&this->%s, %d, tag, %s);", ident(p->sym->name), d, soap_type(typ));
8068        else
8069          fprintf(fout,"soap_embed(soap, (void*)this, (struct soap_array*)&this->%s, 1, tag, %s);", ident(p->sym->name), soap_type(typ));
8070      }
8071      else if (d)
8072        fprintf(fout,"soap_embed(soap, (void*)a, (struct soap_array*)&a->%s, %d, tag, %s);", ident(p->sym->name), d, soap_type(typ));
8073      else
8074        fprintf(fout,"soap_embed(soap, (void*)a, (struct soap_array*)&a->%s, 1, tag, %s);", ident(p->sym->name), soap_type(typ));
8075    }
8076    else if (typ->type == Tclass && !is_external(typ) && !is_volatile(typ) && !is_typedef(typ))
8077      fprintf(fout,"soap_embed(soap, (void*)this, NULL, 0, tag, %s);", soap_type(typ));
8078    else
8079      fprintf(fout,"soap_embed(soap, (void*)a, NULL, 0, tag, %s);", soap_type(typ));
8080  if (typ->type == Tclass && !is_external(typ) && !is_volatile(typ) && !is_typedef(typ))
8081    fprintf(fout,"\n\tif (this->soap_out(soap, tag, id, type))\n\t\treturn soap->error;");
8082  else
8083    fprintf(fout,"\n\tif (soap_out_%s(soap, tag, id, a, type))\n\t\treturn soap->error;", ci);
8084  if (!is_invisible(typ->id->name))
8085    fprintf(fout,"\n\treturn soap_putindependent(soap);\n}");
8086  else
8087    fprintf(fout,"\n\treturn SOAP_OK;\n}");
8088  fflush(fout);
8089}
8090
8091Entry *
8092is_dynamic_array(Tnode *typ)
8093{ Entry *p;
8094  Table *t;
8095  if ((typ->type == Tstruct || typ->type == Tclass) && typ->ref)
8096  { for (t = (Table*)typ->ref; t; t = t->prev)
8097    { p = t->list;
8098      while (p && p->info.typ->type == Tfun)
8099        p = p->next;
8100      if (p && p->info.typ->type == Tpointer && !strncmp(ident(p->sym->name), "__ptr", 5))
8101        if (p->next && (p->next->info.typ->type == Tint || p->next->info.typ->type == Tulong || (p->next->info.typ->type == Tarray && (((Tnode*)p->next->info.typ->ref)->type == Tint || ((Tnode*)p->next->info.typ->ref)->type == Tuint))) && !strcmp(ident(p->next->sym->name), "__size"))
8102	  return p;
8103    }
8104  }
8105  return 0;
8106}
8107
8108Entry *
8109is_discriminant(Tnode *typ)
8110{ Entry *p;
8111  Table *t;
8112  if ((typ->type == Tstruct || typ->type == Tclass) && typ->ref)
8113  { for (t = (Table*)typ->ref; t; t = t->prev)
8114    { p = t->list;
8115      if (p && p->info.typ->type == Tint && !strncmp(ident(p->sym->name), "__union", 7))
8116        if (p->next && p->next->info.typ->type == Tunion && !p->next->next)
8117	  return p;
8118    }
8119  }
8120  return 0;
8121}
8122
8123int
8124get_Darraydims(Tnode *typ)
8125{ Entry *p;
8126  Table *t;
8127  if ((typ->type == Tstruct || typ->type == Tclass) && typ->ref)
8128  { for (t = (Table*)typ->ref; t; t = t->prev)
8129    { p = t->list;
8130      while (p && p->info.typ->type == Tfun)
8131        p = p->next;
8132      if (p && p->info.typ->type == Tpointer && !strncmp(ident(p->sym->name), "__ptr", 5))
8133        if (p->next && p->next->info.typ->type == Tarray && (((Tnode*)p->next->info.typ->ref)->type == Tint || ((Tnode*)p->next->info.typ->ref)->type == Tuint) && !strcmp(ident(p->next->sym->name), "__size"))
8134          return get_dimension(p->next->info.typ);
8135    }
8136  }
8137  return 0;
8138}
8139
8140int
8141has_offset(Tnode *typ)
8142{ Entry *p;
8143  Table *t;
8144  if (typ->type == Tstruct || typ->type == Tclass)
8145  { for (t = (Table*)typ->ref; t; t = t->prev)
8146    { for (p = t->list; p; p = p->next)
8147      { if ((p->info.typ->type == Tint || (p->info.typ->type == Tarray && ((Tnode*)p->info.typ->ref)->type == Tint)) && !strcmp(ident(p->sym->name), "__offset"))
8148          return 1;
8149      }
8150    }
8151  }
8152  return 0;
8153}
8154
8155int
8156is_boolean(Tnode *typ)
8157{ if (typ->type == Tenum)
8158  { if (typ->ref == booltable)
8159      return 1;
8160    else
8161    { size_t n = strlen(ident(typ->id->name));
8162      return n >= 7 && is_eq(ident(typ->id->name) + n - 7, "boolean");
8163    }
8164  }
8165  return 0;
8166}
8167
8168int
8169is_hexBinary(Tnode *typ)
8170{ Entry *p;
8171  Table *t;
8172  size_t n = strlen(ident(typ->id->name));
8173  if ((typ->type == Tstruct || typ->type == Tclass) && n >= 9 && is_eq(ident(typ->id->name) + n - 9, "hexBinary"))
8174  { for (t = (Table*)typ->ref; t; t = t->prev)
8175    { p = t->list;
8176      while (p && p->info.typ->type == Tfun)
8177        p = p->next;
8178      if (p && p->info.typ->type == Tpointer && ((Tnode*)p->info.typ->ref)->type == Tuchar && !strcmp(ident(p->sym->name), "__ptr"))
8179      { p = p->next;
8180        return p && (p->info.typ->type == Tint || p->info.typ->type == Tuint) && !strcmp(ident(p->sym->name), "__size");
8181      }
8182    }
8183  }
8184  return 0;
8185}
8186
8187int
8188is_binary(Tnode *typ)
8189{ Entry *p;
8190  Table *t;
8191  if (!has_ns(typ) && !is_element(typ))
8192    return 0;
8193  if (typ->type == Tstruct || typ->type == Tclass)
8194  { for (t = (Table*)typ->ref; t; t = t->prev)
8195    { p = t->list;
8196      while (p && p->info.typ->type == Tfun)
8197        p = p->next;
8198      if (p && p->info.typ->type == Tpointer && ((Tnode*)p->info.typ->ref)->type == Tuchar && !strcmp(ident(p->sym->name), "__ptr"))
8199      { p = p->next;
8200        return p && (p->info.typ->type == Tint || p->info.typ->type == Tuint) && !strcmp(ident(p->sym->name), "__size");
8201      }
8202    }
8203  }
8204  return 0;
8205}
8206
8207int
8208is_attachment(Tnode *typ)
8209{ Entry *p;
8210  Table *t;
8211  if (!is_binary(typ) || is_transient(typ))
8212    return 0;
8213  for (t = (Table*)typ->ref; t; t = t->prev)
8214  { for (p = t->list; p; p = p->next)
8215    { if (is_string(p->info.typ) && !strcmp(p->sym->name, "id"))
8216      { p = p->next;
8217        if (!p || !is_string(p->info.typ) || strcmp(p->sym->name, "type"))
8218          break;
8219        p = p->next;
8220        if (!p || !is_string(p->info.typ) || strcmp(p->sym->name, "options"))
8221          break;
8222        return 1;
8223      }
8224    }
8225  }
8226  return 0;
8227}
8228
8229int
8230is_mutable(Tnode *typ)
8231{ return is_header_or_fault(typ);
8232}
8233
8234int
8235is_header_or_fault(Tnode *typ)
8236{ if (typ->type == Tpointer || typ->type == Treference)
8237    return is_header_or_fault(typ->ref);
8238  return (typ->type == Tstruct || typ->type == Tclass) && (!strcmp(ident(typ->id->name), "SOAP_ENV__Header") || !strcmp(ident(typ->id->name), "SOAP_ENV__Fault") || !strcmp(ident(typ->id->name), "SOAP_ENV__Code") || !strcmp(ident(typ->id->name), "SOAP_ENV__Detail") || !strcmp(ident(typ->id->name), "SOAP_ENV__Reason"));
8239}
8240
8241int
8242is_body(Tnode *typ)
8243{ if (typ->type == Tpointer || typ->type == Treference)
8244    return is_body(typ->ref);
8245  return (typ->type == Tstruct || typ->type == Tclass) && !strcmp(ident(typ->id->name), "SOAP_ENV__Body");
8246}
8247
8248int
8249is_soap12(const char *enc)
8250{ return !strcmp(envURI, "http://www.w3.org/2003/05/soap-envelope") || (enc && !strcmp(enc, "http://www.w3.org/2003/05/soap-encoding"));
8251}
8252
8253int
8254is_document(const char *style)
8255{ return (!eflag && !style) || (style && !strcmp(style, "document"));
8256}
8257
8258int
8259is_literal(const char *encoding)
8260{ return (!eflag && !encoding) || (encoding && !strcmp(encoding, "literal"));
8261}
8262
8263char *
8264has_soapref(Tnode *typ)
8265{ Entry *p;
8266  Table *t;
8267  if (typ->type == Tstruct || typ->type == Tclass)
8268  { for (t = (Table*)typ->ref; t; t = t->prev)
8269    { for (p = t->list; p; p = p->next)
8270        if (p->info.typ->type == Tpointer && ((Tnode*)p->info.typ->ref)->type == Tstruct && ((Tnode*)p->info.typ->ref)->id == lookup("soap"))
8271          return ident(p->sym->name);
8272    }
8273  }
8274  return NULL;
8275}
8276
8277int
8278has_constructor(Tnode *typ)
8279{ Entry *p, *q;
8280  Table *t;
8281  if (typ->type == Tclass)
8282    for (t = (Table*)typ->ref; t; t = t->prev)
8283      for (p = t->list; p; p = p->next)
8284        if (p->info.typ->type == Tfun && !strcmp(p->sym->name, typ->id->name) && ((FNinfo *)p->info.typ->ref)->ret->type == Tnone)
8285	{ q = ((FNinfo*)p->info.typ->ref)->args->list;
8286          if (!q)
8287	    return 1;
8288        }
8289  return 0;
8290}
8291
8292int
8293has_destructor(Tnode *typ)
8294{ Entry *p;
8295  Table *t;
8296  if (typ->type == Tclass)
8297    for (t = (Table*)typ->ref; t; t = t->prev)
8298      for (p = t->list; p; p = p->next)
8299        if (p->info.typ->type == Tfun && *p->sym->name == '~')
8300	  return 1;
8301  return 0;
8302}
8303
8304int
8305has_getter(Tnode *typ)
8306{ Entry *p, *q;
8307  Table *t;
8308  if (typ->type == Tclass)
8309    for (t = (Table*)typ->ref; t; t = t->prev)
8310      for (p = t->list; p; p = p->next)
8311        if (p->info.typ->type == Tfun && !strcmp(p->sym->name, "get") && ((FNinfo *)p->info.typ->ref)->ret->type == Tint)
8312	{ q = ((FNinfo*)p->info.typ->ref)->args->list;
8313          if (q && q->info.typ->type == Tpointer && ((Tnode*)q->info.typ->ref)->type == Tstruct && ((Tnode*)q->info.typ->ref)->id == lookup("soap"))
8314	    return 1;
8315        }
8316  return 0;
8317}
8318
8319int
8320has_setter(Tnode *typ)
8321{ Entry *p, *q;
8322  Table *t;
8323  if (typ->type == Tclass)
8324    for (t = (Table*)typ->ref; t; t = t->prev)
8325      for (p = t->list; p; p = p->next)
8326        if (p->info.typ->type == Tfun && !strcmp(p->sym->name, "set") && ((FNinfo *)p->info.typ->ref)->ret->type == Tint)
8327	{ q = ((FNinfo*)p->info.typ->ref)->args->list;
8328          if (q && q->info.typ->type == Tpointer && ((Tnode*)q->info.typ->ref)->type == Tstruct && ((Tnode*)q->info.typ->ref)->id == lookup("soap"))
8329	    return 1;
8330        }
8331  return 0;
8332}
8333
8334int
8335is_primitive_or_string(Tnode *typ)
8336{ return is_primitive(typ) || is_string(typ) || is_wstring(typ) || is_stdstring(typ) || is_stdwstring(typ);
8337}
8338
8339int
8340is_primitive(Tnode *typ)
8341{ return typ->type <= Tenum;
8342}
8343
8344int
8345is_string(Tnode *typ)
8346{ return typ->type == Tpointer && ((Tnode*)typ->ref)->type == Tchar && !((Tnode*)typ->ref)->sym;
8347}
8348
8349int
8350is_wstring(Tnode *typ)
8351{ return typ->type == Tpointer && ((Tnode*)typ->ref)->type == Twchar && !((Tnode*)typ->ref)->sym;
8352}
8353
8354int
8355is_stdstring(Tnode *typ)
8356{ return typ->type == Tclass && typ->id == lookup("std::string");
8357}
8358
8359int
8360is_stdwstring(Tnode *typ)
8361{ return typ->type == Tclass && typ->id == lookup("std::wstring");
8362}
8363
8364int
8365is_stdstr(Tnode *typ)
8366{ if (typ->type == Tpointer)
8367    return is_stdstring(typ->ref) || is_stdwstring(typ->ref);
8368  return is_stdstring(typ) || is_stdwstring(typ);
8369}
8370
8371int
8372is_typedef(Tnode *typ)
8373{ return typ->sym && !is_transient(typ) && !is_external(typ);
8374}
8375
8376int
8377reflevel(Tnode *typ)
8378{ int level;
8379  for (level = 0; typ->type == Tpointer; level++)
8380    typ = (Tnode*)typ->ref;
8381  return level;
8382}
8383
8384Tnode *
8385reftype(Tnode *typ)
8386{ while ((typ->type == Tpointer && !is_string(typ) && !is_wstring(typ)) || typ->type == Treference)
8387    typ = typ->ref;
8388  return typ;
8389}
8390
8391void
8392soap_set_attr(Tnode *typ, char *obj, char *name, char *tag)
8393{ if (is_qname(typ))
8394    fprintf(fout, "\n\tif (%s->%s)\n\t\tsoap_set_attr(soap, \"%s\", soap_QName2s(soap, %s->%s));", obj, name, tag, obj, name);
8395  else if (is_string(typ))
8396    fprintf(fout, "\n\tif (%s->%s)\n\t\tsoap_set_attr(soap, \"%s\", %s->%s);", obj, name, tag, obj, name);
8397  else if (is_wstring(typ))
8398    fprintf(fout, "\n\tif (%s->%s)\n\t\tsoap_set_attr(soap, \"%s\", soap_wchar2s(soap, %s->%s));", obj, name, tag, obj, name);
8399  else if (is_stdqname(typ))
8400    fprintf(fout, "\n\tif (!%s->%s.empty())\n\t\tsoap_set_attr(soap, \"%s\", soap_QName2s(soap, %s->%s.c_str()));", obj, name, tag, obj, name);
8401  else if (is_stdstring(typ))
8402    fprintf(fout, "\n\tif (!%s->%s.empty())\n\t\tsoap_set_attr(soap, \"%s\", %s->%s.c_str());", obj, name, tag, obj, name);
8403  else if (is_stdwstring(typ))
8404    fprintf(fout, "\n\tif (!%s->%s.empty())\n\t\tsoap_set_attr(soap, \"%s\", soap_wchar2s(soap, %s->%s.c_str()));", obj, name, tag, obj, name);
8405  else if (typ->type == Tllong || typ->type == Tullong)
8406    fprintf(fout, "\n\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, %s->%s));", tag, c_type(typ), obj, name);
8407  else if (typ->type == Tenum)
8408    fprintf(fout, "\n\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, %s->%s));", tag, c_ident(typ), obj, name);
8409  else if (typ->type == Tpointer)
8410  { Tnode *ptr = typ->ref;
8411    fprintf(fout, "\n\tif (%s->%s)", obj, name);
8412    if (is_qname(ptr))
8413      fprintf(fout, "\n\t\tif (*%s->%s)\n\t\t\tsoap_set_attr(soap, \"%s\", soap_QName2s(soap, *%s->%s));", obj, name, tag, obj, name);
8414    else if (is_string(ptr))
8415      fprintf(fout, "\n\t\tif (*%s->%s)\n\t\t\tsoap_set_attr(soap, \"%s\", *%s->%s);", obj, name, tag, obj, name);
8416    else if (ptr->type == Tllong || ptr->type == Tullong)
8417      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, *%s->%s));", tag, c_type(ptr), obj, name);
8418    else if (ptr->type == Tenum)
8419      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, *%s->%s));", tag, c_ident(ptr), obj, name);
8420    else if (is_stdqname(ptr))
8421      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_QName2s(soap, %s->%s->c_str()));", tag, obj, name);
8422    else if (is_stdstring(ptr))
8423      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", %s->%s->c_str());", tag, obj, name);
8424    else if (is_stdwstring(ptr))
8425      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_wchar2s(soap, %s->%s->c_str()));", tag, obj, name);
8426    else if (is_primitive(ptr))
8427      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, *%s->%s));", tag, the_type(ptr), obj, name);
8428    else if (is_hexBinary(ptr))
8429      fprintf(fout, "\n\t\tif (%s->%s->__ptr)\n\t\t\tsoap_set_attr(soap, \"%s\", soap_s2hex(soap, %s->%s->__ptr, NULL, %s->%s->__size));", obj, name, tag, obj, name, obj, name);
8430    else if (is_binary(ptr))
8431      fprintf(fout, "\n\t\tif (%s->%s->__ptr)\n\t\t\tsoap_set_attr(soap, \"%s\", soap_s2base64(soap, %s->%s->__ptr, NULL, %s->%s->__size));", obj, name, tag, obj, name, obj, name);
8432    else if (is_anyAttribute(ptr))
8433      fprintf(fout, "\n\t\tif (soap_out_%s(soap, \"%s\", -1, %s->%s, \"%s\"))\n\t\t\treturn soap->error;", c_ident(ptr), tag, obj, name, xsi_type_u(ptr));
8434    else if (is_external(ptr))
8435      fprintf(fout, "\n\t\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, *%s->%s));", tag, c_ident(ptr), obj, name);
8436    else
8437    { sprintf(errbuf, "Field '%s' cannot be serialized as an XML attribute", name);
8438      semwarn(errbuf);
8439    }
8440  }
8441  else if (is_primitive(typ))
8442    fprintf(fout, "\n\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, %s->%s));", tag, the_type(typ), obj, name);
8443  else if (is_hexBinary(typ))
8444    fprintf(fout, "\n\tif (%s->%s.__ptr)\n\t\tsoap_set_attr(soap, \"%s\", soap_s2hex(soap, %s->%s.__ptr, NULL, %s->%s.__size));", obj, name, tag, obj, name, obj, name);
8445  else if (is_binary(typ))
8446    fprintf(fout, "\n\tif (%s->%s.__ptr)\n\t\tsoap_set_attr(soap, \"%s\", soap_s2base64(soap, %s->%s.__ptr, NULL, %s->%s.__size));", obj, name, tag, obj, name, obj, name);
8447  else if (is_anyAttribute(typ))
8448    fprintf(fout, "\n\tif (soap_out_%s(soap, \"%s\", -1, &%s->%s, \"%s\"))\n\t\treturn soap->error;", c_ident(typ), tag, obj, name, xsi_type_u(typ));
8449  else if (is_external(typ))
8450    fprintf(fout, "\n\tsoap_set_attr(soap, \"%s\", soap_%s2s(soap, %s->%s));", tag, c_ident(typ), obj, name);
8451  else
8452  { sprintf(errbuf, "Field '%s' cannot be serialized as an XML attribute", name);
8453    semwarn(errbuf);
8454  }
8455}
8456
8457void
8458soap_attr_value(Entry *p, char *obj, char *name, char *tag)
8459{ int flag = 0;
8460  Tnode *typ = p->info.typ;
8461  if (p->info.maxOccurs == 0)
8462    flag = 2; /* prohibited */
8463  else if (p->info.minOccurs >= 1 && !p->info.hasval)
8464    flag = 1; /* required */
8465  if (typ->type == Tllong || typ->type == Tullong)
8466    fprintf(fout, "\n\tif (soap_s2%s(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", c_type(typ), tag, flag, obj, name);
8467  else if (typ->type == Tenum)
8468    fprintf(fout, "\n\tif (soap_s2%s(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", c_ident(typ), tag, flag, obj, name);
8469  else if (is_qname(typ))
8470    fprintf(fout, "\n\tif (soap_s2QName(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", tag, flag, obj, name);
8471  else if (is_string(typ))
8472    fprintf(fout, "\n\tif (soap_s2string(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", tag, flag, obj, name);
8473  else if (is_wstring(typ))
8474    fprintf(fout, "\n\tif (soap_s2wchar(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", tag, flag, obj, name);
8475  else if (is_stdqname(typ))
8476    fprintf(fout, "\n\t{\tconst char *t = soap_attr_value(soap, \"%s\", %d);\n\t\tif (t)\n\t\t{\tchar *s;\n\t\t\tif (soap_s2QName(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\t%s->%s.assign(s);\n\t\t}\n\t}", tag, flag, obj, name);
8477  else if (is_stdstring(typ))
8478    fprintf(fout, "\n\t{\tconst char *t = soap_attr_value(soap, \"%s\", %d);\n\t\tif (t)\n\t\t{\tchar *s;\n\t\t\tif (soap_s2string(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\t%s->%s.assign(s);\n\t\t}\n\t}", tag, flag, obj, name);
8479  else if (is_stdwstring(typ))
8480    fprintf(fout, "\n\t{\tconst char *t = soap_attr_value(soap, \"%s\", %d);\n\t\tif (t)\n\t\t{\twchar_t *s;\n\t\t\tif (soap_s2wchar(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\t%s->%s.assign(s);\n\t\t}\n\t}", tag, flag, obj, name);
8481  else if (typ->type == Tpointer)
8482  { Tnode *ptr = typ->ref;
8483    if (!is_anyAttribute(ptr))
8484      fprintf(fout, "\n\t{\tconst char *t = soap_attr_value(soap, \"%s\", %d);\n\t\tif (t)\n\t\t{", tag, flag);
8485    if (!is_stdstring(ptr))
8486      fprintf(fout, "\n\t\t\tif (!(%s->%s = (%s)soap_malloc(soap, sizeof(%s))))\n\t\t\t{\tsoap->error = SOAP_EOM;\n\t\t\t\treturn NULL;\n\t\t\t}", obj, name, c_type(typ), c_type(ptr));
8487    if (ptr->type == Tllong || ptr->type == Tullong)
8488      fprintf(fout, "\n\t\t\tif (soap_s2%s(soap, t, %s->%s))\n\t\t\treturn NULL;", c_type(ptr), obj, name);
8489    else if (ptr->type == Tenum)
8490      fprintf(fout, "\n\t\t\tif (soap_s2%s(soap, t, %s->%s))\n\t\t\treturn NULL;", c_ident(ptr), obj, name);
8491    else if (is_qname(ptr))
8492      fprintf(fout, "\n\t\t\tif (soap_s2QName(soap, t, %s->%s))\n\t\t\t\treturn NULL;", obj, name);
8493    else if (is_string(ptr))
8494      fprintf(fout, "\n\t\t\tif (soap_s2string(soap, t, %s->%s))\n\t\t\t\treturn NULL;", obj, name);
8495    else if (is_stdqname(ptr))
8496      fprintf(fout, "\n\t\t\tchar *s = NULL;\n\t\t\tif (soap_s2QName(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\tif (s)\n\t\t\t{\t%s->%s = soap_new_std__string(soap, -1);\n\t\t\t\t%s->%s->assign(s);\n\t\t\t}", obj, name, obj, name);
8497    else if (is_stdstring(ptr))
8498      fprintf(fout, "\n\t\t\tchar *s = NULL;\n\t\t\tif (soap_s2string(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\tif (s)\n\t\t\t{\t%s->%s = soap_new_std__string(soap, -1);\n\t\t\t\t%s->%s->assign(s);\n\t\t\t}", obj, name, obj, name);
8499    else if (is_stdwstring(ptr))
8500      fprintf(fout, "\n\t\t\twchar_t *s = NULL;\n\t\t\tif (soap_s2wchar(soap, t, &s))\n\t\t\t\treturn NULL;\n\t\t\tif (s)\n\t\t\t{\t%s->%s = soap_new_std__wstring(soap, -1);\n\t\t\t\t%s->%s->assign(s);\n\t\t\t}", obj, name, obj, name);
8501    else if (is_hexBinary(ptr))
8502      fprintf(fout, "\n\t\t\tif (!(%s->%s->__ptr = (unsigned char*)soap_hex2s(soap, soap_attr_value(soap, \"%s\", %d), NULL, 0, &%s->%s->__size)))\n\t\t\t\treturn NULL;", obj, name, tag, flag, obj, name);
8503    else if (is_binary(ptr))
8504      fprintf(fout, "\n\t\t\tif (!(%s->%s->__ptr = (unsigned char*)soap_base642s(soap, soap_attr_value(soap, \"%s\", %d), NULL, 0, &%s->%s->__size)))\n\t\t\t\treturn NULL;", obj, name, tag, flag, obj, name);
8505    else if (is_anyAttribute(ptr))
8506      fprintf(fout, "\n\t\t\t%s->%s = soap_in_%s(soap, \"%s\", %s->%s, \"%s\");", obj, name, c_ident(ptr), tag, obj, name, xsi_type(ptr));
8507    else if (is_external(ptr))
8508      fprintf(fout, "\n\t\t\tif (soap_s2%s(soap, t, %s->%s))\n\t\t\t\treturn NULL;", c_ident(ptr), obj, name);
8509    else
8510      fprintf(fout, "\n\t\t\tif (soap_s2%s(soap, t, %s->%s))\n\t\t\t\treturn NULL;", the_type(ptr), obj, name);
8511    if (!is_anyAttribute(ptr))
8512      fprintf(fout, "\n\t\t}\n\t}");
8513  }
8514  else if (is_hexBinary(typ))
8515    fprintf(fout, "\n\tif (!(%s->%s.__ptr = (unsigned char*)soap_hex2s(soap, soap_attr_value(soap, \"%s\", %d), NULL, 0, &%s->%s.__size)))\n\t\treturn NULL;", obj, name, tag, flag, obj, name);
8516  else if (is_binary(typ))
8517    fprintf(fout, "\n\tif (!(%s->%s.__ptr = (unsigned char*)soap_base642s(soap, soap_attr_value(soap, \"%s\", %d), NULL, 0, &%s->%s.__size)))\n\t\treturn NULL;", obj, name, tag, flag, obj, name);
8518  else if (is_primitive(typ))
8519    fprintf(fout, "\n\tif (soap_s2%s(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", the_type(typ), tag, flag, obj, name);
8520  else if (is_anyAttribute(typ))
8521    fprintf(fout, "\n\tsoap_in_%s(soap, \"%s\", &%s->%s, \"%s\");", c_ident(typ), tag, obj, name, xsi_type(typ));
8522  else if (is_external(typ))
8523    fprintf(fout, "\n\tif (soap_s2%s(soap, soap_attr_value(soap, \"%s\", %d), &%s->%s))\n\t\treturn NULL;", c_ident(typ), tag, flag, obj, name);
8524}
8525
8526char *
8527ptr_cast(Table *t, char *name)
8528{ char *s = emalloc(strlen(t->sym->name) + strlen(name) + 6);
8529  sprintf(s, "((%s*)%s)", t->sym->name, name);
8530  return s;
8531}
8532
8533void
8534soap_out(Tnode *typ)
8535{ Table *table,*t;
8536  Entry *p = NULL;
8537  int cardinality,i,j,d;
8538  Tnode *n;
8539  char *nse = ns_qualifiedElement(typ);
8540  char *nsa = ns_qualifiedAttribute(typ);
8541
8542  if (is_dynamic_array(typ))
8543  { soap_out_Darray(typ);
8544    return;
8545  }
8546  if (is_primitive(typ) && typ->type != Tenum)
8547  { if (is_external(typ))
8548    { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
8549      return;
8550    }
8551    fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
8552    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "*a"));
8553    if (typ->type == Tllong || typ->type == Tullong)
8554      fprintf(fout,"\n\treturn soap_out%s(soap, tag, id, a, type, %s);\n}", c_type(typ), soap_type(typ));
8555    else
8556      fprintf(fout,"\n\treturn soap_out%s(soap, tag, id, a, type, %s);\n}", the_type(typ), soap_type(typ));
8557    return;
8558  }
8559  if (is_string(typ))
8560  { if (is_external(typ))
8561    { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, char*const*, const char*);", c_ident(typ));
8562      return;
8563    }
8564    fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, char*const*, const char*);", c_ident(typ));
8565    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, char *const*a, const char *type)\n{", c_ident(typ));
8566    fprintf(fout,"\n\treturn soap_outstring(soap, tag, id, a, type, %s);\n}", soap_type(typ));
8567    return;
8568  }
8569  if (is_wstring(typ))
8570  { if (is_external(typ))
8571    { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, wchar_t*const*, const char*);", c_ident(typ));
8572        return;
8573    }
8574    fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, wchar_t*const*, const char*);", c_ident(typ));
8575    fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, wchar_t *const*a, const char *type)\n{", c_ident(typ));
8576    fprintf(fout,"\n\treturn soap_outwstring(soap, tag, id, a, type, %s);\n}", soap_type(typ));
8577    return;
8578  }
8579  if (is_stdstring(typ))
8580  { fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const std::string*, const char*);", c_ident(typ));
8581    fprintf(fout,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const std::string *s, const char *type)\n{\n\tif ((soap->mode & SOAP_C_NILSTRING) && s->empty())\n\t\treturn soap_element_null(soap, tag, id, type);\n\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, s, %s), type) || soap_string_out(soap, s->c_str(), 0) || soap_element_end_out(soap, tag))\n\t\treturn soap->error;\n\treturn SOAP_OK;\n}", c_ident(typ), soap_type(typ));
8582    return;
8583  }
8584  if (is_stdwstring(typ))
8585  { fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const std::wstring*, const char*);", c_ident(typ));
8586    fprintf(fout,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const std::wstring *s, const char *type)\n{\n\tif ((soap->mode & SOAP_C_NILSTRING) && s->empty())\n\t\treturn soap_element_null(soap, tag, id, type);\n\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, s, %s), type) || soap_wstring_out(soap, s->c_str(), 0) || soap_element_end_out(soap, tag))\n\t\treturn soap->error;\n\treturn SOAP_OK;\n}", c_ident(typ), soap_type(typ));
8587    return;
8588  }
8589  switch(typ->type)
8590  { case Tstruct:
8591      table=(Table*)typ->ref;
8592      if (is_external(typ))
8593      { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
8594        return;
8595      }
8596      fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
8597      fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "*a"));
8598      for (t = table; t; t = t->prev)
8599      {	for (p = t->list; p; p = p->next)
8600	{ if (is_repetition(p))
8601	    p = p->next;
8602	  else if (p->info.sto & Sattribute)
8603	    soap_set_attr(p->info.typ, "a", ident(p->sym->name), ns_add(p->sym->name, nsa));
8604	  else if (is_qname(p->info.typ))
8605            fprintf(fout,"\n\tconst char *soap_tmp_%s = soap_QName2s(soap, a->%s);", ident(p->sym->name), ident(p->sym->name));
8606	  else if (is_stdqname(p->info.typ))
8607            fprintf(fout,"\n\tstd::string soap_tmp_%s(soap_QName2s(soap, a->%s.c_str()));", ident(p->sym->name), ident(p->sym->name));
8608	  else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8609            fprintf(fout,"\n\tconst char *soap_tmp_%s = a->%s ? soap_QName2s(soap, *a->%s) : NULL;", ident(p->sym->name), ident(p->sym->name), ident(p->sym->name));
8610	  else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8611            fprintf(fout,"\n\tstd::string soap_temp_%s(a->%s ? soap_QName2s(soap, a->%s->c_str()) : \"\"), *soap_tmp_%s = a->%s ? &soap_temp_%s : NULL;", ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name));
8612        }
8613      }
8614     if (is_primclass(typ))
8615     {
8616	for (table = (Table*)typ->ref; table; table = table->prev)
8617	{ p = table->list;
8618	  if (p && is_item(p))
8619	    break;
8620        }
8621	  if ((p->info.sto & SmustUnderstand) && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && !is_transient(p->info.typ) && !is_void(p->info.typ) && p->info.typ->type != Tfun)
8622	    fprintf(fout, "\n\tsoap->mustUnderstand = 1;");
8623	  if(p->info.typ->type==Tarray)
8624	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, a->%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8625	  else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8626	    fprintf(fout,"\n\treturn a->%s.soap_out(soap, tag, id, \"%s\");", ident(p->sym->name), xsi_type_u(typ));
8627	  else if (is_qname(p->info.typ))
8628	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)&soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8629	  else if (is_stdqname(p->info.typ))
8630	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8631	  else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8632	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)soap_tmp_%s, \"%s\");", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type_u(typ));
8633	  else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8634	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8635	  else if (is_XML(p->info.typ) && is_string(p->info.typ))
8636	    fprintf(fout,"\n\treturn soap_outliteral(soap, tag, &a->%s, NULL);", ident(p->sym->name));
8637	  else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8638	    fprintf(fout,"\n\treturn soap_outwliteral(soap, tag, &a->%s, NULL);", ident(p->sym->name));
8639	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8640	    fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &a->%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8641	  else
8642            fprintf(fout,"\n\treturn SOAP_OK;");
8643      fprintf(fout,"\n}");
8644   }
8645   else
8646   {  if (!is_invisible(typ->id->name))
8647        fprintf(fout,"\n\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, %s), type))\n\t\treturn soap->error;", soap_type(typ));
8648      fflush(fout);
8649      for (t = table; t; t = t->prev)
8650      {	for (p = t->list; p; p = p->next)
8651	{ if (p->info.sto & Sreturn)
8652	  { if (nse || has_ns_eq(NULL, p->sym->name))
8653	    { if (p->info.typ->type == Tpointer)
8654	        fprintf(fout,"\n\tif (a->%s)\n\t\tsoap_element_result(soap, \"%s\");", ident(p->sym->name), ns_add(p->sym->name, nse));
8655              else
8656	        fprintf(fout,"\n\tsoap_element_result(soap, \"%s\");", ns_add(p->sym->name, nse));
8657	    }
8658	  }
8659	  if ((p->info.sto & SmustUnderstand) && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !is_transient(p->info.typ) && !is_void(p->info.typ) && p->info.typ->type != Tfun)
8660	    fprintf(fout, "\n\tsoap->mustUnderstand = 1;");
8661	  needs_lang(p);
8662	  if (p->info.sto & (Sconst | Sprivate | Sprotected))
8663	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
8664	  else if (is_transient(p->info.typ))
8665	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
8666	  else if (p->info.sto & Sattribute)
8667	    ;
8668	  else if (is_repetition(p))
8669	  { fprintf(fout,"\n\tif (a->%s)", ident(p->next->sym->name));
8670            fprintf(fout,"\n\t{\tint i;\n\t\tfor (i = 0; i < a->%s; i++)", ident(p->sym->name));
8671            if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
8672              fprintf(fout,"\n\t\t\tif (a->%s[i].soap_out(soap, \"%s\", -1, \"%s\"))\n\t\t\t\treturn soap->error;", ident(p->next->sym->name), ns_add(p->next->sym->name, nse),xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8673	    else if (is_qname(p->next->info.typ->ref))
8674              fprintf(fout,"\n\t\t{\tconst char *soap_tmp_%s = soap_QName2s(soap, a->%s[i]);\n\t\t\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\t\t\treturn soap->error;\n\t\t}", ident(p->next->sym->name), ident(p->next->sym->name), c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), ident(p->next->sym->name), xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8675            else if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
8676	      fprintf(fout,"\n\t\t\tsoap_outliteral(soap, \"%s\", a->%s + i, NULL);", ns_add(p->next->sym->name, nse), ident(p->next->sym->name));
8677            else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
8678	      fprintf(fout,"\n\t\t\tsoap_outwliteral(soap, \"%s\", a->%s + i, NULL);", ns_add(p->next->sym->name, nse), ident(p->next->sym->name));
8679	    else
8680              fprintf(fout,"\n\t\t\tif (soap_out_%s(soap, \"%s\", -1, a->%s + i, \"%s\"))\n\t\t\t\treturn soap->error;", c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), ident(p->next->sym->name), xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8681            fprintf(fout,"\n\t}");
8682            p = p->next;
8683	  }
8684	  else if (is_anytype(p))
8685	  { fprintf(fout,"\n\tif (soap_putelement(soap, a->%s, \"%s\", -1, a->%s))\n\t\treturn soap->error;", ident(p->next->sym->name), ns_add(p->next->sym->name, nse), ident(p->sym->name));
8686            p = p->next;
8687	  }
8688	  else if (is_choice(p))
8689	  { fprintf(fout,"\n\tif (soap_out_%s(soap, a->%s, &a->%s))\n\t\treturn soap->error;", c_ident(p->next->info.typ), ident(p->sym->name), ident(p->next->sym->name));
8690            p = p->next;
8691	  }
8692	  else if (p->info.typ->type==Tarray)
8693	    fprintf(fout,"\n\tsoap_out_%s(soap, \"%s\", -1, a->%s, \"%s\");", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8694	  else if (p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8695	    fprintf(fout,"\n\tif (a->%s.soap_out(soap, \"%s\", -1, \"%s\"))\n\t\treturn soap->error;", ident(p->sym->name), ns_add(p->sym->name, nse), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8696	  else if (is_qname(p->info.typ))
8697	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8698	  else if (is_stdqname(p->info.typ))
8699	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8700	  else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8701	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ->ref), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8702	  else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8703	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8704	  else if (is_XML(p->info.typ) && is_string(p->info.typ))
8705	    fprintf(fout,"\n\tsoap_outliteral(soap, \"%s\", &a->%s, NULL);", ns_add(p->sym->name, nse), ident(p->sym->name));
8706	  else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8707	    fprintf(fout,"\n\tsoap_outwliteral(soap, \"%s\", &a->%s, NULL);", ns_add(p->sym->name, nse), ident(p->sym->name));
8708	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8709	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &a->%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ),ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8710	}
8711      }
8712      if (!is_invisible(typ->id->name))
8713        fprintf(fout,"\n\treturn soap_element_end_out(soap, tag);\n}");
8714      else
8715        fprintf(fout,"\n\treturn SOAP_OK;\n}");
8716    }
8717    fflush(fout);
8718    break;
8719
8720    case Tclass:
8721      table=(Table*)typ->ref;
8722      if (!is_volatile(typ) && !is_typedef(typ))
8723      {
8724        if (is_external(typ))
8725        { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
8726          return;
8727        }
8728        fprintf(fout,"\n\nint %s::soap_out(struct soap *soap, const char *tag, int id, const char *type) const", ident(typ->id->name));
8729        fprintf(fout,"\n{\n\treturn soap_out_%s(soap, tag, id, this, type);\n}", c_ident(typ));
8730      }
8731      fprintf(fhead,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ), c_type_id(typ, "*"));
8732      fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)\n{", c_ident(typ), c_type_id(typ, "*a"));
8733      fflush(fout);
8734      if (has_setter(typ))
8735        fprintf(fout, "\n\t((%s)a)->set(soap);", c_type_id(typ, "*"));
8736      for (t = table; t; t = t->prev)
8737      {	for (p = t->list; p; p = p->next)
8738	{ if (is_repetition(p))
8739	    p = p->next;
8740	  else if (p->info.sto & Sattribute)
8741	    soap_set_attr(p->info.typ, ptr_cast(t, "a"), ident(p->sym->name), ns_add(p->sym->name, nsa));
8742	  else if (is_qname(p->info.typ))
8743            fprintf(fout,"\n\tconst char *soap_tmp_%s = soap_QName2s(soap, a->%s);", ident(p->sym->name), ident(p->sym->name));
8744	  else if (is_stdqname(p->info.typ))
8745            fprintf(fout,"\n\tstd::string soap_tmp_%s(soap_QName2s(soap, a->%s.c_str()));", ident(p->sym->name), ident(p->sym->name));
8746	  else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8747            fprintf(fout,"\n\tconst char *soap_tmp_%s = a->%s ? soap_QName2s(soap, *a->%s) : NULL;", ident(p->sym->name), ident(p->sym->name), ident(p->sym->name));
8748	  else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8749            fprintf(fout,"\n\tstd::string soap_temp_%s(a->%s ? soap_QName2s(soap, a->%s->c_str()) : \"\"), *soap_tmp_%s = a->%s ? &soap_temp_%s : NULL;", ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name), ident(p->sym->name));
8750        }
8751     }
8752     if (is_primclass(typ))
8753     {
8754	for (t = table; t; t = t->prev)
8755	{ p = t->list;
8756	  if (p && is_item(p))
8757	    break;
8758        }
8759	  if ((p->info.sto & SmustUnderstand) && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && !is_transient(p->info.typ) && !is_void(p->info.typ) && p->info.typ->type != Tfun)
8760	    fprintf(fout, "\n\tsoap->mustUnderstand = 1;");
8761	  if (table->prev)
8762	  {
8763	    if (is_XML(p->info.typ) && is_string(p->info.typ))
8764	      fprintf(fout,"\n\treturn soap_outliteral(soap, tag, &(a->%s::%s), \"%s\");", ident(t->sym->name), ident(p->sym->name), xsi_type(typ));
8765	    else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8766	      fprintf(fout,"\n\treturn soap_outwliteral(soap, tag, &(a->%s::%s), \"%s\");", ident(t->sym->name), ident(p->sym->name), xsi_type(typ));
8767	    else if(p->info.typ->type==Tarray)
8768	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, a->%s::%s, \"%s\");", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name), xsi_type(typ));
8769	    else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8770	      fprintf(fout,"\n\treturn (a->%s::%s).soap_out(soap, tag, id, \"%s\");", ident(t->sym->name), ident(p->sym->name), xsi_type(typ));
8771	    else if (is_qname(p->info.typ))
8772	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)&soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type(typ));
8773	    else if (is_stdqname(p->info.typ))
8774	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type(typ));
8775	    else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8776	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)&soap_tmp_%s, \"%s\");", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type_u(typ));
8777	    else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8778	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8779	    else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8780	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &(a->%s::%s), \"%s\");", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name), xsi_type(typ));
8781	    else
8782              fprintf(fout,"\n\treturn SOAP_OK;");
8783	  }
8784	  else
8785	  { if (is_XML(p->info.typ) && is_string(p->info.typ))
8786	      fprintf(fout,"\n\treturn soap_outliteral(soap, tag, &(a->%s::%s), NULL);", ident(t->sym->name), ident(p->sym->name));
8787	    else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8788	      fprintf(fout,"\n\treturn soap_outwliteral(soap, tag, &(a->%s::%s), NULL);", ident(t->sym->name), ident(p->sym->name));
8789	    else if(p->info.typ->type==Tarray)
8790	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, a->%s::%s, \"%s\");", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name), xsi_type_u(typ));
8791	    else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8792	      fprintf(fout,"\n\treturn (a->%s::%s).soap_out(soap, tag, id, \"%s\");", ident(t->sym->name), ident(p->sym->name), xsi_type_u(typ));
8793	    else if (is_qname(p->info.typ))
8794	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)&soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8795	    else if (is_stdqname(p->info.typ))
8796	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ), ident(p->sym->name), xsi_type_u(typ));
8797	    else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8798	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, (char*const*)&soap_tmp_%s, \"%s\");", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type_u(typ));
8799	    else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8800	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &soap_tmp_%s, \"%s\");", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type_u(typ));
8801	    else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8802	      fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, &a->%s::%s, \"%s\");", c_ident(p->info.typ), ident(t->sym->name), ident(p->sym->name), xsi_type_u(typ));
8803	    else
8804              fprintf(fout,"\n\treturn SOAP_OK;");
8805	  }
8806       fprintf(fout,"\n}");
8807     }
8808     else
8809     { if (!is_invisible(typ->id->name))
8810       { if (table && table->prev)
8811           fprintf(fout,"\n\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, %s), \"%s\"))\n\t\treturn soap->error;", soap_type(typ), xsi_type(typ));
8812         else
8813           fprintf(fout,"\n\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, %s), type))\n\t\treturn soap->error;", soap_type(typ));
8814       }
8815       fflush(fout);
8816
8817      i=0;
8818      /* Get the depth of the inheritance hierarchy */
8819      for (t = table; t; t = t->prev)
8820	i++;
8821
8822      /* Call routines to output the member data of the class */
8823      /* Data members of the Base Classes are outputed first
8824	 followed by the data members of the Derived classes.
8825	 Overridden data members are output twice once for the base class
8826	 they are defined in and once for the derived class that overwrites
8827	 them */
8828
8829      for (; i > 0; i--)
8830      { t = table;
8831	for (j = 0; j< i-1; j++)
8832	  t = t->prev;
8833	for (p = t->list; p != (Entry*) 0; p = p->next)
8834	{ if (p->info.sto & Sreturn)
8835	  { if (nse || has_ns_eq(NULL, p->sym->name))
8836	    { if (p->info.typ->type == Tpointer)
8837	        fprintf(fout,"\n\tif (a->%s)\n\t\tsoap_element_result(soap, \"%s\");", ident(p->sym->name), ns_add(p->sym->name, nse));
8838              else
8839	        fprintf(fout,"\n\tsoap_element_result(soap, \"%s\");", ns_add(p->sym->name, nse));
8840	    }
8841	  }
8842	  if ((p->info.sto & SmustUnderstand) && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && !is_transient(p->info.typ) && !is_void(p->info.typ) && p->info.typ->type != Tfun)
8843	    fprintf(fout, "\n\tsoap->mustUnderstand = 1;");
8844	  needs_lang(p);
8845	  if (is_item(p))
8846	    ;
8847	  else if (p->info.sto & (Sconst | Sprivate | Sprotected))
8848	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
8849	  else if (is_transient(p->info.typ))
8850	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
8851	  else if (p->info.sto & Sattribute)
8852	    ;
8853	  else if (is_repetition(p))
8854	  { fprintf(fout,"\n\tif (a->%s::%s)", ident(t->sym->name), ident(p->next->sym->name));
8855            fprintf(fout,"\n\t{\tint i;\n\t\tfor (i = 0; i < a->%s::%s; i++)", ident(t->sym->name), ident(p->sym->name));
8856            if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
8857              fprintf(fout,"\n\t\t\tif (a->%s::%s[i].soap_out(soap, \"%s\", -1, \"%s\"))\n\t\t\t\treturn soap->error;", ident(t->sym->name), ident(p->next->sym->name), ns_add_overridden(t, p->next, nse),xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8858	    else if (is_qname(p->next->info.typ->ref))
8859              fprintf(fout,"\n\t\t{\tconst char *soap_tmp_%s = soap_QName2s(soap, a->%s[i]);\n\t\t\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\t\t\treturn soap->error;\n\t\t}", ident(p->next->sym->name), ident(p->next->sym->name), c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), ident(p->next->sym->name), xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8860            else if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
8861	      fprintf(fout,"\n\t\t\tsoap_outliteral(soap, \"%s\", a->%s::%s + i, NULL);", ns_add(p->next->sym->name, nse), ident(t->sym->name), ident(p->next->sym->name));
8862            else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
8863              fprintf(fout,"\n\t\t\tsoap_outwliteral(soap, \"%s\", a->%s::%s + i, NULL);", ns_add(p->next->sym->name, nse), ident(t->sym->name), ident(p->next->sym->name));
8864            else
8865              fprintf(fout,"\n\t\t\tif (soap_out_%s(soap, \"%s\", -1, a->%s::%s + i, \"%s\"))\n\t\t\t\treturn soap->error;", c_ident(p->next->info.typ->ref), ns_add_overridden(t, p->next, nse), ident(t->sym->name), ident(p->next->sym->name), xsi_type_cond_u(p->next->info.typ->ref, !has_ns_eq(NULL, p->next->sym->name)));
8866            fprintf(fout,"\n\t}");
8867            p = p->next;
8868	  }
8869	  else if (is_anytype(p))
8870	  { fprintf(fout,"\n\tif (soap_putelement(soap, a->%s::%s, \"%s\", -1, a->%s::%s))\n\t\treturn soap->error;", ident(t->sym->name), ident(p->next->sym->name), ns_add(p->sym->name, nse), ident(t->sym->name), ident(p->sym->name));
8871            p = p->next;
8872	  }
8873	  else if (is_choice(p))
8874	  { fprintf(fout,"\n\tif (soap_out_%s(soap, a->%s::%s, &a->%s::%s))\n\t\treturn soap->error;", c_ident(p->next->info.typ), ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name));
8875            p = p->next;
8876	  }
8877	  else if (p->info.typ->type==Tarray)
8878	    fprintf(fout,"\n\tsoap_out_%s(soap, \"%s\", -1, a->%s::%s, \"%s\");", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8879	  else if (p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8880	    fprintf(fout,"\n\tif ((a->%s::%s).soap_out(soap, \"%s\", -1, \"%s\"))\n\t\treturn soap->error;", ident(t->sym->name), ident(p->sym->name), ns_add_overridden(t, p, nse),xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8881	  else if (is_qname(p->info.typ))
8882	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8883	  else if (is_stdqname(p->info.typ))
8884	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8885	  else if (p->info.typ->type == Tpointer && is_qname(p->info.typ->ref))
8886	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ->ref), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8887	  else if (p->info.typ->type == Tpointer && is_stdqname(p->info.typ->ref))
8888	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &soap_tmp_%s, \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8889	  else if (is_XML(p->info.typ) && is_string(p->info.typ))
8890	    fprintf(fout,"\n\tsoap_outliteral(soap, \"%s\", &(a->%s::%s), NULL);", ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name));
8891	  else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8892	    fprintf(fout,"\n\tsoap_outwliteral(soap, \"%s\", &(a->%s::%s), NULL);", ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name));
8893	  else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8894	    fprintf(fout,"\n\tif (soap_out_%s(soap, \"%s\", -1, &(a->%s::%s), \"%s\"))\n\t\treturn soap->error;", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8895  	  fflush(fout);
8896	}
8897       }
8898       if (!is_invisible(typ->id->name))
8899         fprintf(fout,"\n\treturn soap_element_end_out(soap, tag);\n}");
8900       else
8901         fprintf(fout,"\n\treturn SOAP_OK;\n}");
8902      }
8903      fflush(fout);
8904      break;
8905
8906    case Tunion:
8907      if (is_external(typ))
8908      { fprintf(fhead, "\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, int, const %s);", c_ident(typ), c_type_id(typ, "*"));
8909        return;
8910      }
8911      fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, int, const %s);", c_ident(typ), c_type_id(typ, "*"));
8912      fprintf(fout, "\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, int choice, const %s)\n{", c_ident(typ), c_type_id(typ, "*a"));
8913      table = (Table*)typ->ref;
8914      fprintf(fout, "\n\tswitch (choice)\n\t{");
8915      for (p = table->list; p; p = p->next)
8916      { if (p->info.sto & (Sconst | Sprivate | Sprotected))
8917	  fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
8918	else if (is_transient(p->info.typ))
8919	  fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
8920	else if (p->info.sto & Sattribute)
8921	  ;
8922	else if (is_repetition(p))
8923	  ;
8924	else if (is_anytype(p))
8925	  ;
8926	else if (p->info.typ->type == Tarray)
8927	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8928	  fprintf(fout, "\n\t\treturn soap_out_%s(soap, \"%s\", -1, a->%s, \"%s\");", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8929	}
8930	else if (p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
8931	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8932	  fprintf(fout, "\n\t\treturn a->%s.soap_out(soap, \"%s\", -1, \"%s\");", ident(p->sym->name), ns_add(p->sym->name, nse), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8933	}
8934	else if (is_qname(p->info.typ) || is_stdqname(p->info.typ))
8935	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8936          fprintf(fout,"\n\t{\tconst char *soap_tmp_%s = soap_QName2s(soap, a->%s);", ident(p->sym->name), ident(p->sym->name));
8937	  fprintf(fout,"\n\t\treturn soap_out_%s(soap, \"%s\", -1, (char*const*)&soap_tmp_%s, \"%s\");\n\t}", c_ident(p->info.typ),ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8938	}
8939	else if (is_XML(p->info.typ) && is_string(p->info.typ))
8940	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8941	  fprintf(fout,"\n\t\treturn soap_outliteral(soap, \"%s\", &a->%s, NULL);", ns_add(p->sym->name, nse), ident(p->sym->name));
8942	}
8943	else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
8944	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8945	  fprintf(fout,"\n\t\treturn soap_outwliteral(soap, \"%s\", &a->%s, NULL);", ns_add(p->sym->name, nse), ident(p->sym->name));
8946	}
8947	else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
8948	{ fprintf(fout, "\n\tcase SOAP_UNION_%s_%s:", c_ident(typ), ident(p->sym->name));
8949	  fprintf(fout,"\n\t\treturn soap_out_%s(soap, \"%s\", -1, &a->%s, \"%s\");", c_ident(p->info.typ),ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type_cond_u(p->info.typ, !has_ns_eq(NULL, p->sym->name)));
8950        }
8951      }
8952      fprintf(fout, "\n\tdefault:\n\t\tbreak;\n\t}\n\treturn SOAP_OK;\n}");
8953      fflush(fout);
8954      break;
8955
8956    case Tpointer:
8957      if (is_external(typ))
8958      { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char *, int, %s, const char *);", c_ident(typ),c_type_id(typ, "const*"));
8959        return;
8960      }
8961      fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char *, int, %s, const char *);", c_ident(typ),c_type_id(typ, "const*"));
8962      fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "const*a"));
8963      if (is_template(typ))
8964      { fprintf(fout,"\n\tif (!*a)");
8965        fprintf(fout,"\n\t\treturn soap_element_null(soap, tag, id, type);");
8966        fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, *a, type);", c_ident(typ->ref));
8967      }
8968      else
8969      { p = is_dynamic_array(typ->ref);
8970        if (p)
8971        { d = get_Darraydims(typ->ref);
8972	  if (d)
8973            fprintf(fout,"\n\tid = soap_element_id(soap, tag, id, *a, (struct soap_array*)&(*a)->%s, %d, type, %s);", ident(p->sym->name), d, soap_type(typ->ref));
8974	  else
8975            fprintf(fout,"\n\tid = soap_element_id(soap, tag, id, *a, (struct soap_array*)&(*a)->%s, 1, type, %s);", ident(p->sym->name), soap_type(typ->ref));
8976        }
8977	else
8978          fprintf(fout,"\n\tid = soap_element_id(soap, tag, id, *a, NULL, 0, type, %s);", soap_type(typ->ref));
8979	fprintf(fout,"\n\tif (id < 0)\n\t\treturn soap->error;");
8980        if (((Tnode *) typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref) && !is_typedef(typ->ref))
8981	  fprintf(fout,"\n\treturn (*a)->soap_out(soap, tag, id, type);");
8982        else
8983	  fprintf(fout,"\n\treturn soap_out_%s(soap, tag, id, *a, type);",c_ident(typ->ref));
8984      }
8985      fprintf(fout,"\n}");
8986      break;
8987
8988    case Tarray:
8989      if (is_external(typ))
8990      { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, %s, const char*);", c_ident(typ),c_type_id(typ, "const"));
8991        return;
8992      }
8993      fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, %s, const char*);", c_ident(typ),c_type_id(typ, "const"));
8994      fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "const a"));
8995      fprintf(fout,"\n\tint i;");
8996        fprintf(fout,"\n\tsoap_array_begin_out(soap, tag, soap_embedded_id(soap, id, a, %s), \"%s[%d]\", 0);", soap_type(typ), xsi_type_Tarray(typ), get_dimension(typ));
8997      n=typ->ref;
8998      cardinality = 1;
8999      while(n->type==Tarray)
9000	{
9001	  n=n->ref;
9002	  cardinality++;
9003	}
9004
9005      fprintf(fout,"\n\tfor (i = 0; i < %d; i++)\n\t{",get_dimension(typ));
9006     if (((Tnode *)typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref) && !is_typedef(typ->ref))
9007     { if(cardinality>1)
9008         fprintf(fout,"\n\t\ta[i].soap_out(soap, \"item\", -1, \"%s\")", xsi_type_u(typ->ref));
9009       else fprintf(fout,"\n\t\t(a+i)->soap_out(soap, \"item\", -1, \"%s\")", xsi_type_u(typ->ref));
9010     }
9011     else
9012     { if(((Tnode *)typ->ref)->type != Tarray)
9013       { if(((Tnode *)typ->ref)->type == Tpointer)
9014	  fprintf(fout,"\n\t\tsoap->position = 1;\n\t\tsoap->positions[0] = i;\n\t\tsoap_out_%s(soap, \"item\", -1, a", c_ident(typ->ref));
9015	 else
9016	  fprintf(fout,"\n\t\tsoap_out_%s(soap, \"item\", -1, a",c_ident(typ->ref));
9017       }
9018       else
9019         fprintf(fout,"\n\t\tsoap_out_%s(soap, \"item\", -1, a",c_ident(typ->ref));
9020       if(cardinality>1)
9021         fprintf(fout,"[i], \"%s\")", xsi_type_u(typ->ref));
9022       else
9023         fprintf(fout,"+i, \"%s\")", xsi_type_u(typ->ref));
9024      }
9025      if(((Tnode *)typ->ref)->type == Tpointer)
9026        fprintf(fout,";\n\t}\n\tsoap->position = 0;\n\treturn soap_element_end_out(soap, tag);\n}");
9027      else
9028        fprintf(fout,";\n\t}\n\treturn soap_element_end_out(soap, tag);\n}");
9029      break;
9030
9031    case Tenum:
9032      if (is_external(typ))
9033      { fprintf(fhead, "\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ), c_type_id(typ, "*"));
9034        return;
9035      }
9036      fprintf(fhead, "\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ), c_type_id(typ, "*"));
9037      if (!is_typedef(typ))
9038      { fprintf(fout, "\n\nstatic const struct soap_code_map soap_codes_%s[] =\n{", c_ident(typ));
9039        for (t = (Table*)typ->ref; t; t = t->prev)
9040        { for (p = t->list; p; p = p->next)
9041	    fprintf(fout, "\t{ (long)%s, \"%s\" },\n", ident(p->sym->name), ns_remove2(p->sym->name));
9042        }
9043        fprintf(fout, "\t{ 0, NULL }\n");
9044        fprintf(fout, "};");
9045      }
9046      fprintf(fhead, "\n\nSOAP_FMAC3S const char* SOAP_FMAC4S soap_%s2s(struct soap*, %s);", c_ident(typ), c_type(typ));
9047      fprintf(fout, "\n\nSOAP_FMAC3S const char* SOAP_FMAC4S soap_%s2s(struct soap *soap, %s)", c_ident(typ), c_type_id(typ, "n"));
9048      if (is_typedef(typ))
9049        fprintf(fout, "\n{\treturn soap_%s2s(soap, n);\n}", t_ident(typ));
9050      else if (is_boolean(typ))
9051        fprintf(fout, "\n{\treturn soap_code_str(soap_codes_%s, n!=0);\n}", c_ident(typ));
9052      else if (!is_mask(typ))
9053      { fprintf(fout, "\n{\tconst char *s = soap_code_str(soap_codes_%s, (long)n);", c_ident(typ));
9054        fprintf(fout, "\n\tif (s)\n\t\treturn s;");
9055        fprintf(fout, "\n\treturn soap_long2s(soap, (long)n);");
9056        fprintf(fout, "\n}");
9057      }
9058      else
9059        fprintf(fout, "\n{\n\treturn soap_code_list(soap, soap_codes_%s, (long)n);\n}", c_ident(typ));
9060      fprintf(fout, "\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)", c_ident(typ), c_type_id(typ, "*a"));
9061      fprintf(fout, "\n{\tif (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, %s), type)", soap_type(typ));
9062      fprintf(fout, " || soap_send(soap, soap_%s2s(soap, *a)))\n\t\treturn soap->error;", c_ident(typ));
9063      fprintf(fout, "\n\treturn soap_element_end_out(soap, tag);\n}");
9064      break;
9065    case Ttemplate:
9066      if (is_external(typ))
9067      { fprintf(fhead,"\nSOAP_FMAC1 int SOAP_FMAC2 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
9068        return;
9069      }
9070      fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
9071      n = typ->ref;
9072      if (!n)
9073        return;
9074      fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "*a"));
9075
9076      fprintf(fout, "\n\tfor (%s::const_iterator i = a->begin(); i != a->end(); ++i)\n\t{", c_type(typ));
9077      if (n->type==Tarray)
9078	fprintf(fout,"\n\t\tif (soap_out_%s(soap, tag, id, *i, \"%s\"))", c_ident(n), xsi_type_u(typ));
9079      else if (n->type==Tclass && !is_external(n) && !is_volatile(n) && !is_typedef(n))
9080	fprintf(fout,"\n\t\tif ((*i).soap_out(soap, tag, id, \"%s\"))", xsi_type_u(typ));
9081      else if (is_qname(n))
9082        fprintf(fout,"\n\t\tconst char *soap_tmp = soap_QName2s(soap, *i);\n\t\tif (soap_out_%s(soap, tag, id, (char*const*)&soap_tmp, \"%s\"))", c_ident(n), xsi_type_u(typ));
9083      else if (is_stdqname(n))
9084        fprintf(fout,"\n\t\tstd::string soap_tmp(soap_QName2s(soap, (*i).c_str()));\n\t\tif (soap_out_%s(soap, tag, id, &soap_tmp, \"%s\"))", c_ident(n), xsi_type_u(typ));
9085      else if (is_XML(n) && is_string(n))
9086        fprintf(fout,"\n\t\tif (soap_outliteral(soap, tag, &(*i), NULL))");
9087      else if (is_XML(n) && is_wstring(n))
9088        fprintf(fout,"\n\t\tif (soap_outwliteral(soap, tag, &(*i), NULL))");
9089      else if (n->type == Tenum && n->ref == booltable)
9090	fprintf(fout,"\n\t\tbool b = (*i);\n\t\tif (soap_out_%s(soap, tag, id, &b, \"%s\"))", c_ident(n), xsi_type_u(typ));
9091      else
9092	fprintf(fout,"\n\t\tif (soap_out_%s(soap, tag, id, &(*i), \"%s\"))", c_ident(n), xsi_type_u(typ));
9093      fprintf(fout, "\n\t\t\treturn soap->error;");
9094      fprintf(fout, "\n\t}\n\treturn SOAP_OK;\n}");
9095      break;
9096    default: break;
9097    }
9098}
9099
9100void
9101soap_out_Darray(Tnode *typ)
9102{ int i, j, d = 0;
9103  Table *t, *table;
9104  Entry *p, *q;
9105  char *nse = ns_qualifiedElement(typ);
9106  char *nsa = ns_qualifiedAttribute(typ);
9107  char *item;
9108
9109  table=(Table*)typ->ref;
9110  fprintf(fhead,"\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap*, const char*, int, const %s, const char*);", c_ident(typ),c_type_id(typ, "*"));
9111      if (is_external(typ))
9112        return;
9113  if (typ->type == Tclass && !is_volatile(typ) && !is_typedef(typ))
9114  { fprintf(fout,"\n\nint %s::soap_out(struct soap *soap, const char *tag, int id, const char *type) const", c_type(typ));
9115    fprintf(fout,"\n{\treturn soap_out_%s(soap, tag, id, this, type);\n}", c_ident(typ));
9116  }
9117  fflush(fout);
9118  fprintf(fout,"\n\nSOAP_FMAC3 int SOAP_FMAC4 soap_out_%s(struct soap *soap, const char *tag, int id, const %s, const char *type)\n{", c_ident(typ),c_type_id(typ, "*a"));
9119  if (has_setter(typ))
9120    fprintf(fout, "\n\t((%s)a)->set(soap);", c_type_id(typ, "*"));
9121  if (!is_binary(typ))
9122  { d = get_Darraydims(typ);
9123    if (d)
9124      fprintf(fout,"\n\tint i, n = soap_size(a->__size, %d);", d);
9125    else
9126      fprintf(fout,"\n\tint i, n = a->__size;");
9127  }
9128  if (typ->type == Tclass)
9129  { for (t = table; t; t = t->prev)
9130    {	for (p = t->list; p; p = p->next)
9131	{ if (p->info.sto & Sattribute)
9132	    soap_set_attr(p->info.typ, ptr_cast(t, "a"), ident(p->sym->name), ns_add(p->sym->name, nsa));
9133        }
9134    }
9135  }
9136  else
9137  { for (t = table; t; t = t->prev)
9138    {	for (p = t->list; p; p = p->next)
9139	{ if (p->info.sto & Sattribute)
9140	    soap_set_attr(p->info.typ, "a", ident(p->sym->name), ns_add(p->sym->name, nsa));
9141        }
9142    }
9143  }
9144  p = is_dynamic_array(typ);
9145  if (p->sym->name[5])
9146    item = ns_add(p->sym->name + 5, nse);
9147  else
9148    item = ns_add("item", nse);
9149  q = table->list;
9150  if (!has_ns(typ) && !is_untyped(typ) && !is_binary(typ))
9151  { if (is_untyped(p->info.typ))
9152    { if (has_offset(typ))
9153        if (d)
9154          fprintf(fout,"\n\tchar *t = soap_putsizesoffsets(soap, \"%s\", a->__size, a->__offset, %d);", wsdl_type(p->info.typ, "xsd"), d);
9155        else
9156          fprintf(fout,"\n\tchar *t = soap_putsize(soap, \"%s\", n + a->__offset);", wsdl_type(p->info.typ, "xsd"));
9157      else if (d)
9158	fprintf(fout,"\n\tchar *t = soap_putsizes(soap, \"%s\", a->__size, %d);", wsdl_type(p->info.typ, "xsd"), d);
9159      else
9160        fprintf(fout,"\n\tchar *t = soap_putsize(soap, \"%s\", n);", wsdl_type(p->info.typ, "xsd"));
9161    }
9162    else
9163    { if (has_offset(typ))
9164        if (d)
9165          fprintf(fout,"\n\tchar *t = soap_putsizesoffsets(soap, \"%s\", a->__size, a->__offset, %d);", xsi_type(typ), d);
9166        else
9167          fprintf(fout,"\n\tchar *t = soap_putsize(soap, \"%s\", n + a->__offset);",xsi_type(typ));
9168      else if (d)
9169        fprintf(fout,"\n\tchar *t = soap_putsizes(soap, \"%s\", a->__size, %d);", xsi_type(typ),d);
9170      else
9171        fprintf(fout,"\n\tchar *t = soap_putsize(soap, \"%s\", a->__size);" ,xsi_type(typ));
9172    }
9173  }
9174  if (d)
9175    fprintf(fout,"\n\tid = soap_element_id(soap, tag, id, a, (struct soap_array*)&a->%s, %d, type, %s);", ident(p->sym->name), d, soap_type(typ));
9176  else if (is_attachment(typ))
9177  { fprintf(fout,"\n#ifndef WITH_LEANER\n\tid = soap_attachment(soap, tag, id, a, (struct soap_array*)&a->%s, a->id, a->type, a->options, 1, type, %s);", ident(p->sym->name), soap_type(typ));
9178    fprintf(fout,"\n#else\n\tid = soap_element_id(soap, tag, id, a, (struct soap_array*)&a->%s, 1, type, %s);\n#endif", ident(p->sym->name), soap_type(typ));
9179  }
9180  else
9181    fprintf(fout,"\n\tid = soap_element_id(soap, tag, id, a, (struct soap_array*)&a->%s, 1, type, %s);", ident(p->sym->name), soap_type(typ));
9182  fprintf(fout,"\n\tif (id < 0)\n\t\treturn soap->error;");
9183  fprintf(fout,"\n\tif (");
9184  if (has_ns(typ) || is_untyped(typ) || is_binary(typ))
9185  { if (table->prev)
9186      fprintf(fout,"soap_element_begin_out(soap, tag, id, \"%s\")", xsi_type(typ));
9187    else
9188      fprintf(fout,"soap_element_begin_out(soap, tag, id, type)");
9189  }
9190  else if (has_offset(typ))
9191  { if (d)
9192      fprintf(fout,"soap_array_begin_out(soap, tag, id, t, soap_putoffsets(soap, a->__offset, %d))", d);
9193    else
9194      fprintf(fout,"soap_array_begin_out(soap, tag, id, t, soap_putoffset(soap, a->__offset))");
9195  }
9196  else
9197    fprintf(fout,"soap_array_begin_out(soap, tag, id, t, NULL)");
9198  fprintf(fout, ")\n\t\treturn soap->error;");
9199  if (is_binary(typ) && !is_hexBinary(typ))
9200    fprintf(fout, "\n\tif (soap_putbase64(soap, a->__ptr, a->__size))\n\t\treturn soap->error;");
9201  else if (is_hexBinary(typ))
9202    fprintf(fout, "\n\tif (soap_puthex(soap, a->__ptr, a->__size))\n\t\treturn soap->error;");
9203  else
9204  { fprintf(fout,"\n\tfor (i = 0; i < n; i++)\n\t{");
9205    if (!has_ns(typ) && !is_untyped(typ))
9206    { if (d)
9207      { fprintf(fout,"\n\t\tsoap->position = %d;", d);
9208        for (i = 0; i < d; i++)
9209	{ fprintf(fout, "\n\t\tsoap->positions[%d] = i", i);
9210          for (j = i+1; j < d; j++)
9211	    fprintf(fout, "/a->__size[%d]", j);
9212	  fprintf(fout, "%%a->__size[%d];", i);
9213        }
9214        if (is_XML(p->info.typ->ref) && is_string(p->info.typ->ref))
9215          fprintf(fout,"\n\t\tsoap_outliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9216        else if (is_XML(p->info.typ->ref) && is_wstring(p->info.typ->ref))
9217          fprintf(fout,"\n\t\tsoap_outwliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9218        else if (((Tnode *)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
9219          fprintf(fout,"\n\t\ta->%s[i].soap_out(soap, \"item\", -1, \"%s\");", ident(p->sym->name), xsi_type_u(((Tnode *)p->info.typ->ref)));
9220	else
9221	  fprintf(fout, "\n\t\tsoap_out_%s(soap, \"%s\", -1, &a->%s[i], \"%s\");",c_ident(((Tnode *)p->info.typ->ref)), item, ident(p->sym->name), xsi_type_u(((Tnode *)p->info.typ->ref)));
9222      }
9223      else
9224      { fprintf(fout,"\n\t\tsoap->position = 1;\n\t\tsoap->positions[0] = i;");
9225        if (is_XML(p->info.typ->ref) && is_string(p->info.typ->ref))
9226          fprintf(fout,"\n\t\tsoap_outliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9227        else if (is_XML(p->info.typ->ref) && is_wstring(p->info.typ->ref))
9228          fprintf(fout,"\n\t\tsoap_outwliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9229        else if (((Tnode *)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
9230          fprintf(fout,"\n\t\ta->%s[i].soap_out(soap, \"%s\", -1, \"%s\");", ident(p->sym->name), item, xsi_type_u(((Tnode *)p->info.typ->ref)));
9231	else
9232          fprintf(fout,"\n\t\tsoap_out_%s(soap, \"%s\", -1, &a->%s[i], \"%s\");",c_ident(((Tnode *)p->info.typ->ref)), item, ident(p->sym->name), xsi_type_u(((Tnode *)p->info.typ->ref)));
9233      }
9234    }
9235    else
9236    { if (is_XML(p->info.typ->ref) && is_string(p->info.typ->ref))
9237        fprintf(fout,"\n\t\tsoap_outliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9238      else if (is_XML(p->info.typ->ref) && is_wstring(p->info.typ->ref))
9239        fprintf(fout,"\n\t\tsoap_outwliteral(soap, \"%s\", &a->%s[i], NULL);", item, ident(p->sym->name));
9240      else if (((Tnode *)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
9241        fprintf(fout,"\n\t\ta->%s[i].soap_out(soap, \"%s\", -1, \"%s\");", ident(p->sym->name), item, xsi_type_u(((Tnode *)p->info.typ->ref)));
9242      else
9243        fprintf(fout,"\n\t\tsoap_out_%s(soap, \"%s\", -1, &a->%s[i], \"%s\");",c_ident(((Tnode *)p->info.typ->ref)), item, ident(p->sym->name), xsi_type_u(((Tnode *)p->info.typ->ref)));
9244    }
9245  }
9246  if (is_binary(typ))
9247    fprintf(fout,"\n\treturn soap_element_end_out(soap, tag);\n}");
9248  else if (!has_ns(typ) && !is_untyped(typ))
9249    fprintf(fout,"\n\t}\n\tsoap->position = 0;\n\treturn soap_element_end_out(soap, tag);\n}");
9250  else
9251    fprintf(fout,"\n\t}\n\treturn soap_element_end_out(soap, tag);\n}");
9252}
9253
9254void
9255soap_get(Tnode *typ)
9256{
9257  Tnode *temp;
9258
9259  if (typ->type == Ttemplate || typ->type == Tunion)
9260    return;
9261
9262  if(typ->type==Tarray)
9263    {
9264      /* ARRAY */
9265      temp = typ;
9266      while(temp->type == Tarray){
9267	temp = temp->ref;
9268      }
9269      fprintf(fhead,"\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_get_%s(struct soap*, %s, const char*, const char*);", c_type(temp),c_ident(typ),c_type(typ));
9270      fprintf(fout,"\n\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_get_%s(struct soap *soap, %s, const char *tag, const char *type)", c_type(temp),c_ident(typ),c_type_id(typ, "a"));
9271      fprintf(fout,"\n{\t%s;",c_type_id(temp, "(*p)"));
9272      fprintf(fout,"\n\tif ((p = soap_in_%s(soap, tag, a, type)))", c_ident(typ));
9273    }
9274  else if(typ->type==Tclass && !is_external(typ) && !is_volatile(typ) && !is_typedef(typ))
9275    {
9276      /* CLASS  */
9277      fprintf(fout,"\n\nvoid *%s::soap_get(struct soap *soap, const char *tag, const char *type)", c_type(typ));
9278      fprintf(fout,"\n{\n\treturn soap_get_%s(soap, this, tag, type);\n}", c_ident(typ));
9279      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_get_%s(struct soap*, %s, const char*, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9280      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_get_%s(struct soap *soap, %s, const char *tag, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*p"));
9281      fprintf(fout,"\n\tif ((p = soap_in_%s(soap, tag, p, type)))", c_ident(typ));
9282    }
9283  else
9284    {
9285      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_get_%s(struct soap*, %s, const char*, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9286      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_get_%s(struct soap *soap, %s, const char *tag, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*p"));
9287      fprintf(fout,"\n\tif ((p = soap_in_%s(soap, tag, p, type)))", c_ident(typ));
9288    }
9289  fprintf(fout,"\n\t\tif (soap_getindependent(soap))\n\t\t\treturn NULL;");
9290  fprintf(fout,"\n\treturn p;\n}");
9291  fflush(fout);
9292}
9293
9294void
9295soap_in(Tnode *typ)
9296{ Entry *p = NULL;
9297  Table *table,*t;
9298  int total,a, cardinality,i,j;
9299  unsigned long m;
9300  Tnode *n, *temp;
9301  char *nse = ns_qualifiedElement(typ);
9302  char *nsa = ns_qualifiedAttribute(typ);
9303  if (is_dynamic_array(typ))
9304  { soap_in_Darray(typ);
9305    return;
9306  }
9307  if (is_primitive_or_string(typ) && typ->type != Tenum)
9308  {
9309      if (is_stdqname(typ))
9310      { fprintf(fhead,"\nSOAP_FMAC3 std::string * SOAP_FMAC4 soap_in_%s(struct soap*, const char*, std::string*, const char*);", c_ident(typ));
9311        fprintf(fout,"\n\nSOAP_FMAC1 std::string * SOAP_FMAC2 soap_in_%s(struct soap *soap, const char *tag, std::string *s, const char *type)\n{\n\tif (soap_element_begin_in(soap, tag, 1, type))\n\t\treturn NULL;\n\tif (!s)\n\t\ts = soap_new_std__string(soap, -1);\n\tif (soap->null)\n\t\tif (s)\n\t\t\ts->erase();", c_ident(typ));
9312        fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{\tchar *t;\n\t\ts = (std::string*)soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::string), soap->type, soap->arrayType);\n\t\tif (s)\n\t\t\tif ((t = soap_string_in(soap, 2, %ld, %ld)))\n\t\t\t\ts->assign(t);\n\t\t\telse\n\t\t\t\treturn NULL;\n\t}\n\telse\n\t\ts = (std::string*)soap_id_forward(soap, soap->href, soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::string), soap->type, soap->arrayType), 0, %s, 0, sizeof(std::string), 0, soap_copy_%s);\n\tif (soap->body && soap_element_end_in(soap, tag))\n\t\treturn NULL;\n\treturn s;\n}", soap_type(typ), typ->minLength, typ->maxLength, soap_type(typ), soap_type(typ), c_ident(typ));
9313        return;
9314      }
9315      if (is_stdstring(typ))
9316      { fprintf(fhead,"\nSOAP_FMAC3 std::string * SOAP_FMAC4 soap_in_%s(struct soap*, const char*, std::string*, const char*);", c_ident(typ));
9317        fprintf(fout,"\n\nSOAP_FMAC1 std::string * SOAP_FMAC2 soap_in_%s(struct soap *soap, const char *tag, std::string *s, const char *type)\n{\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;\n\tif (!s)\n\t\ts = soap_new_std__string(soap, -1);\n\tif (soap->null)\n\t\tif (s)\n\t\t\ts->erase();", c_ident(typ));
9318        fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{\tchar *t;\n\t\ts = (std::string*)soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::string), soap->type, soap->arrayType);\n\t\tif (s)\n\t\t\tif ((t = soap_string_in(soap, 1, %ld, %ld)))\n\t\t\t\ts->assign(t);\n\t\t\telse\n\t\t\t\treturn NULL;\n\t}\n\telse\n\t\ts = (std::string*)soap_id_forward(soap, soap->href, soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::string), soap->type, soap->arrayType), 0, %s, 0, sizeof(std::string), 0, soap_copy_%s);\n\tif (soap->body && soap_element_end_in(soap, tag))\n\t\treturn NULL;\n\treturn s;\n}", soap_type(typ), typ->minLength, typ->maxLength, soap_type(typ), soap_type(typ), c_ident(typ));
9319        return;
9320      }
9321      if (is_stdwstring(typ))
9322      { fprintf(fhead,"\nSOAP_FMAC3 std::wstring * SOAP_FMAC4 soap_in_%s(struct soap*, const char*, std::wstring*, const char*);", c_ident(typ));
9323        fprintf(fout,"\n\nSOAP_FMAC1 std::wstring * SOAP_FMAC2 soap_in_%s(struct soap *soap, const char *tag, std::wstring *s, const char *type)\n{\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;\n\tif (!s)\n\t\ts = soap_new_std__wstring(soap, -1);\n\tif (soap->null)\n\t\tif (s)\n\t\t\ts->erase();", c_ident(typ));
9324        fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{\twchar_t *t;\n\t\ts = (std::wstring*)soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::wstring), soap->type, soap->arrayType);\n\t\tif (s)\n\t\t\tif ((t = soap_wstring_in(soap, 1, %ld, %ld)))\n\t\t\t\ts->assign(t);\n\t\t\telse\n\t\t\t\treturn NULL;\n\t}\n\telse\n\t\ts = (std::wstring*)soap_id_forward(soap, soap->href, soap_class_id_enter(soap, soap->id, s, %s, sizeof(std::wstring), soap->type, soap->arrayType), 0, %s, 0, sizeof(std::wstring), 0, soap_copy_%s);\n\tif (soap->body && soap_element_end_in(soap, tag))\n\t\treturn NULL;\n\treturn s;\n}", soap_type(typ), typ->minLength, typ->maxLength, soap_type(typ), soap_type(typ), c_ident(typ));
9325        return;
9326      }
9327    if (is_external(typ))
9328    { fprintf(fhead,"\nSOAP_FMAC1 %s * SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type(typ), c_ident(typ),c_type_id(typ, "*"));
9329      return;
9330    }
9331    fprintf(fhead,"\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type(typ), c_ident(typ),c_type_id(typ, "*"));
9332    fprintf(fout,"\n\nSOAP_FMAC3 %s * SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{", c_type(typ), c_ident(typ),c_type_id(typ, "*a"));
9333    if (typ->type == Tllong || typ->type == Tullong)
9334      fprintf(fout,"\n\treturn soap_in%s(soap, tag, a, type, %s);\n}", c_type(typ), soap_type(typ));
9335    else if (is_wstring(typ))
9336      fprintf(fout,"\n\treturn soap_inwstring(soap, tag, a, type, %s, %ld, %ld);\n}", soap_type(typ), typ->minLength, typ->maxLength);
9337    else if (is_string(typ))
9338      fprintf(fout,"\n\treturn soap_instring(soap, tag, a, type, %s, %d, %ld, %ld);\n}", soap_type(typ), is_qname(typ)+1, typ->minLength, typ->maxLength);
9339    else
9340      fprintf(fout,"\n\treturn soap_in%s(soap, tag, a, type, %s);\n}", the_type(typ), soap_type(typ));
9341    fflush(fout);
9342    return;
9343  }
9344  switch(typ->type)
9345  { case Tstruct:
9346      if (is_external(typ))
9347      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9348        return;
9349      }
9350      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9351      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
9352      table = (Table *)typ->ref;
9353      if (is_primclass(typ))
9354      { fprintf(fout, "\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;");
9355	if (has_class(typ))
9356          fprintf(fout,"\n\tif (!(a = (%s)soap_class_id_enter(soap, soap->id, a, %s, sizeof(%s), soap->type, soap->arrayType)))\n\t\treturn NULL;", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9357	else
9358          fprintf(fout,"\n\tif (!(a = (%s)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL)))\n\t\treturn NULL;", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9359        fprintf(fout,"\n\tsoap_revert(soap);\n\t*soap->id = '\\0';");
9360	/* fprintf(fout,"\n\tif (soap->alloced)"); */
9361        fprintf(fout,"\n\tsoap_default_%s(soap, a);",c_ident(typ));
9362          for (t = (Table*)typ->ref; t; t = t->prev)
9363          { for (p = t->list; p; p = p->next)
9364	      if (p->info.sto & Sattribute)
9365		soap_attr_value(p, "a", ident(p->sym->name), ns_add(p->sym->name, nsa));
9366	  }
9367      fflush(fout);
9368	for (table = (Table*)typ->ref; table; table = table->prev)
9369	{ p = table->list;
9370	  if (p && is_item(p))
9371	    break;
9372        }
9373	    if (is_XML(p->info.typ) && is_string(p->info.typ))
9374	    { fprintf(fout,"\n\tif (!soap_inliteral(soap, tag, &a->%s))", ident(p->sym->name));
9375	    }
9376	    else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
9377	    { fprintf(fout,"\n\tif (!soap_inwliteral(soap, tag, &a->%s))", ident(p->sym->name));
9378	    }
9379	    else if(p->info.typ->type==Tarray) {
9380	      fprintf(fout,"\n\tif (!soap_in_%s(soap, tag, a->%s, \"%s\"))", c_ident(p->info.typ), ident(p->sym->name), xsi_type(typ));
9381	    }
9382	    else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
9383	      fprintf(fout,"\n\tif (!a->%s.soap_in(soap, tag, \"%s\"))", ident(p->sym->name), xsi_type(typ));
9384	    }
9385	    else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
9386	      fprintf(fout,"\n\tif (!soap_in_%s(soap, tag, &a->%s, \"%s\"))", c_ident(p->info.typ), ident(p->sym->name), xsi_type(typ));
9387	    }
9388           fprintf(fout,"\n\t\treturn NULL;");
9389           fprintf(fout, "\n\treturn a;\n}");
9390      }
9391      else
9392      { table = (Table*)typ->ref;
9393	if (!is_discriminant(typ))
9394        { for (t = table; t; t = t->prev)
9395	  { for (p = t->list; p; p = p->next)
9396	    { if (!(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ))
9397	      { if (is_anytype(p) || is_choice(p))
9398	          p = p->next;
9399		if (is_repetition(p))
9400	        { fprintf(fout,"\n\tstruct soap_blist *soap_blist_%s = NULL;", ident(p->next->sym->name));
9401		  p = p->next;
9402		}
9403		else
9404	          fprintf(fout,"\n\tsize_t soap_flag_%s = %ld;", ident(p->sym->name), p->info.maxOccurs);
9405	      }
9406	    }
9407	  }
9408	}
9409          if (!is_invisible(typ->id->name))
9410          { fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, type))\n\t\treturn NULL;");
9411	  }
9412	  else if (!is_discriminant(typ))
9413            fprintf(fout,"\n\tshort soap_flag;");
9414	  if (has_class(typ))
9415	  { if (is_invisible(typ->id->name))
9416              fprintf(fout,"\n\ta = (%s)soap_class_id_enter(soap, \"\", a, %s, sizeof(%s), soap->type, soap->arrayType);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9417	    else
9418              fprintf(fout,"\n\ta = (%s)soap_class_id_enter(soap, soap->id, a, %s, sizeof(%s), soap->type, soap->arrayType);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9419	  }
9420	  else if (is_invisible(typ->id->name))
9421            fprintf(fout,"\n\ta = (%s)soap_id_enter(soap, \"\", a, %s, sizeof(%s), 0, NULL, NULL, NULL);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9422	  else
9423            fprintf(fout,"\n\ta = (%s)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9424	  fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
9425          /* fprintf(fout,"\n\tif (soap->alloced)"); */
9426          fprintf(fout,"\n\tsoap_default_%s(soap, a);",c_ident(typ));
9427          for (t = table; t; t = t->prev)
9428          { for (p = t->list; p; p = p->next)
9429	      if (p->info.sto & Sattribute)
9430		soap_attr_value(p, "a", ident(p->sym->name), ns_add(p->sym->name, nsa));
9431	  }
9432        if (!is_invisible(typ->id->name))
9433	{ fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{");
9434	  if (!is_discriminant(typ))
9435            fprintf(fout,"\n\t\tfor (;;)\n\t\t{\tsoap->error = SOAP_TAG_MISMATCH;");
9436	}
9437	else if (!is_discriminant(typ))
9438        { if (table->prev || table->list)
9439            fprintf(fout,"\n\t\tfor (soap_flag = 0;; soap_flag = 1)\n\t\t{\tsoap->error = SOAP_TAG_MISMATCH;");
9440	}
9441        a=0;
9442        for (t = table; t; t = t->prev)
9443	{ for (p = t->list; p; p = p->next)
9444	  { if (p->info.sto & (Sconst | Sprivate | Sprotected))
9445	      fprintf(fout, "\n\t\t/* non-serializable %s skipped */", ident(p->sym->name));
9446	    else if (is_transient(p->info.typ))
9447	      fprintf(fout, "\n\t\t/* transient %s skipped */", ident(p->sym->name));
9448	    else if (p->info.sto & Sattribute)
9449	      ;
9450	    else if (is_repetition(p))
9451	    {
9452              fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH && ");
9453	      if (is_unmatched(p->next->sym))
9454                fprintf(fout,"!soap_element_begin_in(soap, NULL, 1, NULL))");
9455	      else if (is_invisible(p->next->sym->name))
9456                fprintf(fout,"!soap_peek_element(soap))");
9457	      else
9458                fprintf(fout,"!soap_element_begin_in(soap, \"%s\", 1, NULL))", ns_add(p->next->sym->name, nse));
9459              fprintf(fout,"\n\t\t\t{\tif (a->%s == NULL)\n\t\t\t\t{\tif (soap_blist_%s == NULL)\n\t\t\t\t\t\tsoap_blist_%s = soap_new_block(soap);\n\t\t\t\t\ta->%s = (%s)soap_push_block(soap, soap_blist_%s, sizeof(%s));\n\t\t\t\t\tif (a->%s == NULL)\n\t\t\t\t\t\treturn NULL;", ident(p->next->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ), ident(p->next->sym->name), c_type(p->next->info.typ->ref), ident(p->next->sym->name));
9460              if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9461                fprintf(fout,"\n\t\t\t\t\t%s p;\n\t\t\t\t\tmemcpy(a->%s, &p, sizeof(%s)); // a bit rough but portable", c_type(p->next->info.typ->ref), ident(p->next->sym->name), c_type(p->next->info.typ->ref));
9462              if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
9463                fprintf(fout,"\n\t\t\t\t\ta->%s->soap_default(soap);", ident(p->next->sym->name));
9464              else if (((Tnode*)p->next->info.typ->ref)->type != Tpointer  && !is_XML(p->next->info.typ->ref))
9465                fprintf(fout,"\n\t\t\t\t\tsoap_default_%s(soap, a->%s);", c_ident(p->next->info.typ->ref), ident(p->next->sym->name));
9466              else
9467                fprintf(fout,"\n\t\t\t\t\t*a->%s = NULL;", ident(p->next->sym->name));
9468              fprintf(fout,"\n\t\t\t\t}");
9469	      if (!is_invisible(p->next->sym->name))
9470                fprintf(fout,"soap_revert(soap);");
9471	      if (is_unmatched(p->next->sym))
9472	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9473                  fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, NULL, a->%s))", ident(p->next->sym->name));
9474                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9475                  fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, NULL, a->%s))", ident(p->next->sym->name));
9476                else
9477                  fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, a->%s, \"%s\"))", c_ident(p->next->info.typ->ref), ident(p->next->sym->name), xsi_type(p->next->info.typ->ref));
9478	      }
9479	      else
9480	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9481                  fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", a->%s))", ns_add(p->next->sym->name, nse), ident(p->next->sym->name));
9482                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9483                  fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", a->%s))", ns_add(p->next->sym->name, nse), ident(p->next->sym->name));
9484                else
9485                  fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s, \"%s\"))", c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), ident(p->next->sym->name), xsi_type(p->next->info.typ->ref));
9486	      }
9487              fprintf(fout,"\n\t\t\t\t{\ta->%s++;\n\t\t\t\t\ta->%s = NULL;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}", ident(p->sym->name), ident(p->next->sym->name));
9488	      /*
9489              fprintf(fout,"\n\t\t\tif (soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)", ident(p->next->sym->name));
9490              if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_volatile(p->next->info.typ->ref))
9491                fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\t%s;\n\t\t\t\tq.soap_default(soap);\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"), c_type_id(p->next->info.typ->ref, "q"));
9492              else if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9493                fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\t%s;\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"), c_type_id(p->next->info.typ->ref, "q"));
9494              else
9495                fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"));
9496	      if (is_unmatched(p->next->sym))
9497                fprintf(fout,"\n\t\t\t\tfor (a->%s = 0; !soap_element_begin_in(soap, NULL, 1, NULL); a->%s++)", ident(p->sym->name), ident(p->sym->name));
9498	      else if (is_invisible(p->next->sym->name))
9499                fprintf(fout,"\n\t\t\t\tfor (a->%s = 0; !soap_peek_element(soap); a->%s++)", ident(p->sym->name), ident(p->sym->name));
9500	      else
9501                fprintf(fout,"\n\t\t\t\tfor (a->%s = 0; !soap_element_begin_in(soap, \"%s\", 1, NULL); a->%s++)", ident(p->sym->name), ns_add(p->next->sym->name, nse), ident(p->sym->name));
9502              fprintf(fout,"\n\t\t\t\t{\tp = (%s)soap_push_block(soap, NULL, sizeof(%s));\n\t\t\t\tif (!p)\n\t\t\t\t\treturn NULL;", c_type(p->next->info.typ), c_type(p->next->info.typ->ref));
9503              if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9504                fprintf(fout,"\n\t\t\t\t\tmemcpy(p, &q, sizeof(%s));", c_type(p->next->info.typ->ref));
9505              if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
9506                fprintf(fout,"\n\t\t\t\t\tp->soap_default(soap);");
9507              else if (((Tnode*)p->next->info.typ->ref)->type != Tpointer  && !is_XML(p->next->info.typ->ref))
9508                fprintf(fout,"\n\t\t\t\t\tsoap_default_%s(soap, p);", c_ident(p->next->info.typ->ref));
9509              else
9510                fprintf(fout,"\n\t\t\t\t\t*p = NULL;");
9511	      if (!is_invisible(p->next->sym->name))
9512                fprintf(fout,"\n\t\t\t\t\tsoap_revert(soap);");
9513	      if (is_unmatched(p->next->sym))
9514	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9515                  fprintf(fout,"\n\t\t\t\t\tif (!soap_inliteral(soap, NULL, p))");
9516                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9517                  fprintf(fout,"\n\t\t\t\t\tif (!soap_inwliteral(soap, NULL, p))");
9518                else
9519                  fprintf(fout,"\n\t\t\t\t\tif (!soap_in_%s(soap, NULL, p, \"%s\"))", c_ident(p->next->info.typ->ref), xsi_type(p->next->info.typ->ref));
9520	      }
9521	      else
9522	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9523                  fprintf(fout,"\n\t\t\t\t\tif (!soap_inliteral(soap, \"%s\", p))", ns_add(p->next->sym->name, nse));
9524                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9525                  fprintf(fout,"\n\t\t\t\t\tif (!soap_inwliteral(soap, \"%s\", p))", ns_add(p->next->sym->name, nse));
9526                else
9527                  fprintf(fout,"\n\t\t\t\t\tif (!soap_in_%s(soap, \"%s\", p, \"%s\"))", c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), xsi_type(p->next->info.typ->ref));
9528	      }
9529              fprintf(fout,"\n\t\t\t\t\t\tbreak;");
9530              fprintf(fout,"\n\t\t\t\t\tsoap_flag_%s = 0;", ident(p->next->sym->name));
9531              fprintf(fout,"\n\t\t\t\t}");
9532              fprintf(fout,"\n\t\t\t\ta->%s = (%s)soap_save_block(soap, NULL, NULL, 1);", ident(p->next->sym->name), c_type(p->next->info.typ));
9533              fprintf(fout,"\n\t\t\t\tif (!soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)\n\t\t\t\t\tcontinue;\n\t\t\t}", ident(p->next->sym->name));
9534	    */
9535            p = p->next;
9536	  }
9537	  else if (is_anytype(p))
9538          { fprintf(fout,"\n\t\t\tif (soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)", ident(p->next->sym->name));
9539	    fprintf(fout,"\n\t\t\t\tif ((a->%s = soap_getelement(soap, &a->%s)))", ident(p->next->sym->name), ident(p->sym->name));
9540	    fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s = 0;", ident(p->next->sym->name));
9541	    fprintf(fout,"\n\t\t\t\t\tcontinue;");
9542	    fprintf(fout,"\n\t\t\t\t}");
9543            p = p->next;
9544	  }
9545          else if (is_discriminant(typ) && p->next)
9546          { fprintf(fout,"\n\t\tif (!soap_in_%s(soap, &a->%s, &a->%s))", c_ident(p->next->info.typ), ident(p->sym->name), ident(p->next->sym->name));
9547            fprintf(fout,"\n\t\t\treturn NULL;");
9548            break;
9549	  }
9550	  else if (is_choice(p))
9551	  { fprintf(fout,"\n\t\t\tif (soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)", ident(p->next->sym->name));
9552	    fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, &a->%s, &a->%s))", c_ident(p->next->info.typ), ident(p->sym->name), ident(p->next->sym->name));
9553	    fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s = 0;", ident(p->next->sym->name));
9554	    fprintf(fout,"\n\t\t\t\t\tcontinue;");
9555	    fprintf(fout,"\n\t\t\t\t}");
9556            p = p->next;
9557	  }
9558	  else
9559	  {
9560	   if (!is_invisible(p->sym->name) && !is_primclass(typ) && p->info.typ->type != Tfun && !is_void(p->info.typ))
9561	   { if (is_string(p->info.typ) || is_wstring(p->info.typ) || is_stdstr(p->info.typ))
9562	       fprintf(fout,"\n\t\t\tif (soap_flag_%s && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))", ident(p->sym->name));
9563	     else if (is_template(p->info.typ))
9564	       fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
9565             else
9566	       fprintf(fout,"\n\t\t\tif (soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)", ident(p->sym->name));
9567	   }
9568	   if (is_unmatched(p->sym))
9569	   {
9570	    if (is_XML(p->info.typ) && is_string(p->info.typ)) {
9571	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, NULL, &a->%s))", ident(p->sym->name));
9572	    } else if (is_XML(p->info.typ) && is_wstring(p->info.typ)) {
9573	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, NULL, &a->%s))", ident(p->sym->name));
9574	    } else if(p->info.typ->type==Tarray) {
9575	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, a->%s, \"%s\"))", c_ident(p->info.typ), ident(p->sym->name), xsi_type(p->info.typ));
9576	    } else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
9577	      fprintf(fout,"\n\t\t\t\tif (a->%s.soap_in(soap, NULL, \"%s\"))", ident(p->sym->name), xsi_type(p->info.typ));
9578	    } else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
9579	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, &a->%s, \"%s\"))", c_ident(p->info.typ), ident(p->sym->name), xsi_type(p->info.typ));
9580	    }
9581	   }
9582	   else if (!is_invisible(p->sym->name))
9583	   {
9584	    if (is_XML(p->info.typ) && is_string(p->info.typ)) {
9585	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
9586	    } else if (is_XML(p->info.typ) && is_wstring(p->info.typ)) {
9587	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
9588	    } else if(p->info.typ->type==Tarray) {
9589	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s, \"%s\"))", c_ident(p->info.typ),ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type(p->info.typ));
9590	    } else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
9591	      fprintf(fout,"\n\t\t\t\tif (a->%s.soap_in(soap, \"%s\", \"%s\"))", ident(p->sym->name), ns_add(p->sym->name, nse),xsi_type(p->info.typ));
9592	    } else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
9593	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", &a->%s, \"%s\"))", c_ident(p->info.typ), ns_add(p->sym->name, nse), ident(p->sym->name), xsi_type(p->info.typ));
9594	    }
9595	   }
9596	    if (!is_invisible(p->sym->name) && !is_primclass(typ) && p->info.typ->type != Tfun && !is_void(p->info.typ))
9597	    { if (is_template(p->info.typ))
9598	        fprintf(fout,"\n\t\t\t\t\tcontinue;");
9599	      else
9600	      { fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s--;", ident(p->sym->name));
9601	        fprintf(fout,"\n\t\t\t\t\tcontinue;");
9602	        fprintf(fout,"\n\t\t\t\t}");
9603	      }
9604	    }
9605	  }
9606	  fflush(fout);
9607	}
9608      }
9609      if (!is_discriminant(typ))
9610      { for (t = table; t; t = t->prev)
9611	{ for (p = t->list; p; p = p->next)
9612	  { if (is_repetition(p) || is_anytype(p) || is_choice(p))
9613	    { p = p->next;
9614	      continue;
9615	    }
9616	    if (is_invisible(p->sym->name)
9617	      && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !is_transient(p->info.typ) && !(p->info.sto & Sattribute))
9618	    { if (is_string(p->info.typ) || is_wstring(p->info.typ) || is_stdstr(p->info.typ))
9619	        fprintf(fout,"\n\t\t\tif (soap_flag_%s && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))", ident(p->sym->name));
9620              else if (is_template(p->info.typ))
9621	        fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
9622              else
9623	        fprintf(fout,"\n\t\t\tif (soap_flag_%s && soap->error == SOAP_TAG_MISMATCH)", ident(p->sym->name));
9624	    if (is_XML(p->info.typ) && is_string(p->info.typ))
9625	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
9626	    else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
9627	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
9628	    else if(p->info.typ->type==Tarray)
9629	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s, \"%s\"))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name),xsi_type(p->info.typ));
9630	    else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
9631	      fprintf(fout,"\n\t\t\t\tif (a->%s.soap_in(soap, \"%s\", \"%s\"))", ident(p->sym->name),ns_add(p->sym->name, nse),xsi_type(p->info.typ));
9632	    else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
9633	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", &a->%s, \"%s\"))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name),xsi_type(p->info.typ));
9634	    if (is_template(p->info.typ))
9635	      fprintf(fout,"\n\t\t\t\t\tcontinue;");
9636	    else
9637	    { fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s--;", ident(p->sym->name));
9638	      fprintf(fout,"\n\t\t\t\t\tcontinue;");
9639	      fprintf(fout,"\n\t\t\t\t}");
9640	    }
9641	   }
9642	  }
9643        }
9644        for (t = table; t; t = t->prev)
9645	  for (p = t->list; p; p = p->next)
9646	    if (p->info.sto & Sreturn)
9647	      if (nse || has_ns_eq(NULL, p->sym->name))
9648	        fprintf(fout,"\n\t\t\tsoap_check_result(soap, \"%s\");", ns_add(p->sym->name, nse));
9649	if (!is_invisible(typ->id->name) || table->prev || table->list)
9650        { fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
9651          if (!is_invisible(typ->id->name) || is_discriminant(typ))
9652            fprintf(fout,"\n\t\t\t\tsoap->error = soap_ignore_element(soap);");
9653          else
9654            fprintf(fout,"\n\t\t\t\tif (soap_flag)\n\t\t\t\t{\tsoap->error = SOAP_OK;\n\t\t\t\t\tbreak;\n\t\t\t\t}");
9655          fprintf(fout,"\n\t\t\tif (soap->error == SOAP_NO_TAG)");
9656          fprintf(fout,"\n\t\t\t\tbreak;");
9657          fprintf(fout,"\n\t\t\tif (soap->error)\n\t\t\t\treturn NULL;");
9658          fprintf(fout,"\n\t\t}");
9659	}
9660      }
9661	if (table && !is_discriminant(typ))
9662	{ for (p = table->list; p; p = p->next)
9663	    if (is_repetition(p))
9664	    { fprintf(fout, "\n\t\tif (a->%s)\n\t\t\tsoap_pop_block(soap, soap_blist_%s);", ident(p->next->sym->name), ident(p->next->sym->name));
9665	      fprintf(fout, "\n\t\tif (a->%s)\n\t\t\ta->%s = (%s)soap_save_block(soap, soap_blist_%s, NULL, 1);\n\t\telse\n\t\t{\ta->%s = NULL;\n\t\t\tif (soap_blist_%s)\n\t\t\t\tsoap_end_block(soap, soap_blist_%s);\n\t\t}", ident(p->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ), ident(p->next->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), ident(p->next->sym->name));
9666	      p = p->next;
9667	    }
9668	}
9669      if (!is_invisible(typ->id->name))
9670      { fprintf(fout,"\n\t\tif (soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
9671        fprintf(fout,"\n\t}\n\telse\n\t{\t");
9672	if (has_class(typ))
9673          fprintf(fout,"a = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, soap_copy_%s);",c_type_id(typ, "*"), soap_type(typ), c_type(typ), c_ident(typ));
9674	else
9675          fprintf(fout,"a = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, NULL);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9676        fprintf(fout,"\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
9677        fprintf(fout, "\n\t}");
9678      }
9679	a = 0;
9680	if (table && !is_discriminant(typ))
9681	{ for (p = table->list; p; p = p->next)
9682	  { if (p->info.minOccurs > 0 && p->info.maxOccurs >= 0 && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ) && !is_repetition(p) && !is_choice(p) && p->info.hasval == False)
9683	    { if (is_item(p))
9684	        continue;
9685	      if (is_anytype(p))
9686	        p = p->next;
9687	      if (a==0)
9688	      { fprintf(fout,"\n\tif (%s(soap_flag_%s > %ld", strict_check(), ident(p->sym->name), p->info.maxOccurs - p->info.minOccurs);
9689	        a=1;
9690              }
9691	      else
9692	        fprintf(fout," || soap_flag_%s > %ld", ident(p->sym->name), p->info.maxOccurs - p->info.minOccurs);
9693	    }
9694	    else if (p->info.typ->minLength > 0 && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ) && !is_repetition(p) && !is_choice(p) && p->info.hasval == False)
9695	    { if (is_item(p))
9696	        continue;
9697	      if (is_anytype(p))
9698	        p = p->next;
9699	      if (a==0)
9700	      { fprintf(fout,"\n\tif (%s(soap_flag_%s > 0", strict_check(), ident(p->sym->name));
9701	        a=1;
9702              }
9703	      else
9704	        fprintf(fout," || soap_flag_%s > 0", ident(p->sym->name));
9705	    }
9706	    else if (is_template(p->info.typ))
9707	    { if (p->info.minOccurs > 1)
9708	      { if (p->info.typ->type == Tpointer)
9709	        { if (a==0)
9710	          { fprintf(fout,"\n\tif (%s(!a->%s || a->%s->size() < %ld", strict_check(), ident(p->sym->name), ident(p->sym->name), p->info.minOccurs);
9711	            a=1;
9712                  }
9713	          else
9714	            fprintf(fout," || !a->%s || a->%s->size() < %ld", ident(p->sym->name), ident(p->sym->name), p->info.minOccurs);
9715	        }
9716	        else
9717	        { if (a==0)
9718	          { fprintf(fout,"\n\tif (%s(a->%s.size() < %ld", strict_check(), ident(p->sym->name), p->info.minOccurs);
9719	            a=1;
9720                  }
9721	          else
9722	            fprintf(fout," || a->%s.size() < %ld", ident(p->sym->name), p->info.minOccurs);
9723	        }
9724	      }
9725	      if ( p->info.maxOccurs > 1)
9726	      { if (p->info.typ->type == Tpointer)
9727	        { if (a==0)
9728	          { fprintf(fout,"\n\tif (%s((a->%s && a->%s->size() > %ld)", strict_check(), ident(p->sym->name), ident(p->sym->name), p->info.maxOccurs);
9729	            a=1;
9730                  }
9731	          else
9732	            fprintf(fout," || (a->%s && a->%s->size() > %ld)", ident(p->sym->name), ident(p->sym->name), p->info.maxOccurs);
9733	        }
9734		else
9735	        { if (a==0)
9736	          { fprintf(fout,"\n\tif (%s(a->%s.size() > %ld", strict_check(), ident(p->sym->name), p->info.maxOccurs);
9737	            a=1;
9738                  }
9739	          else
9740	            fprintf(fout," || a->%s.size() > %ld", ident(p->sym->name), p->info.maxOccurs);
9741	        }
9742	      }
9743	    }
9744	    else if (is_repetition(p))
9745	    { if (p->info.minOccurs > 1)
9746	      { if (a==0)
9747	        { fprintf(fout,"\n\tif (%s(a->%s < %ld", strict_check(), ident(p->sym->name), p->info.minOccurs);
9748	          a=1;
9749                }
9750	        else
9751	          fprintf(fout," || a->%s < %ld", ident(p->sym->name), p->info.minOccurs);
9752	      }
9753	      if (p->info.maxOccurs > 1)
9754	      { if (a==0)
9755	        { fprintf(fout,"\n\tif (%s(a->%s > %ld", strict_check(), ident(p->sym->name), p->info.maxOccurs);
9756	          a=1;
9757                }
9758	        else
9759	          fprintf(fout," || a->%s > %ld", ident(p->sym->name), p->info.maxOccurs);
9760	      }
9761	      p = p->next;
9762	    }
9763	    else if (is_choice(p))
9764	    { if (p->info.minOccurs != 0)
9765	      { if (a==0)
9766	        { fprintf(fout,"\n\tif (%s(soap_flag_%s", strict_check(), ident(p->next->sym->name));
9767	          a=1;
9768                }
9769	        else
9770	          fprintf(fout," || soap_flag_%s", ident(p->next->sym->name));
9771	      }
9772	      p = p->next;
9773	    }
9774	  }
9775	  if (a)
9776	    fprintf(fout,"))\n\t{\tsoap->error = SOAP_OCCURS;\n\t\treturn NULL;\n\t}");
9777	}
9778        fprintf(fout, "\n\treturn a;\n}");
9779      }
9780      break;
9781
9782     case Tclass:
9783      if (is_external(typ))
9784      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9785        return;
9786      }
9787      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
9788      if (!is_volatile(typ) && !is_typedef(typ))
9789      { fprintf(fout,"\n\nvoid *%s::soap_in(struct soap *soap, const char *tag, const char *type)", c_type(typ));
9790	fprintf(fout,"\n{\treturn soap_in_%s(soap, tag, this, type);\n}",c_ident(typ));
9791        fflush(fout);
9792      }
9793      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
9794      if (is_primclass(typ))
9795      {
9796        fprintf(fout, "\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;");
9797        fprintf(fout,"\n\tif (!(a = (%s)soap_class_id_enter(soap, soap->id, a, %s, sizeof(%s), soap->type, soap->arrayType)))\n\t{\tsoap->error = SOAP_TAG_MISMATCH;\n\t\treturn NULL;\n\t}", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9798        fprintf(fout,"\n\tsoap_revert(soap);\n\t*soap->id = '\\0';");
9799        fprintf(fout,"\n\tif (soap->alloced)");
9800        fprintf(fout,"\n\t{\ta->soap_default(soap);");
9801        fprintf(fout,"\n\t\tif (soap->clist->type != %s)", soap_type(typ));
9802        fprintf(fout,"\n\t\t\treturn (%s)a->soap_in(soap, tag, type);", c_type_id(typ, "*"));
9803        fprintf(fout,"\n\t}");
9804          for (t = (Table*)typ->ref; t; t = t->prev)
9805          { for (p = t->list; p; p = p->next)
9806	      if (p->info.sto & Sattribute)
9807		soap_attr_value(p, ptr_cast(t, "a"), ident(p->sym->name), ns_add(p->sym->name, nsa));
9808	  }
9809      fflush(fout);
9810	for (table = (Table*)typ->ref; table; table = table->prev)
9811	{ p = table->list;
9812	  if (p && is_item(p))
9813	    break;
9814        }
9815	    if (is_XML(p->info.typ) && is_string(p->info.typ))
9816	    { fprintf(fout,"\n\tif (!soap_inliteral(soap, tag, &(a->%s::%s)))", ident(table->sym->name), ident(p->sym->name));
9817	    }
9818	    else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
9819	    { fprintf(fout,"\n\tif (!soap_inwliteral(soap, tag, &(a->%s::%s)))", ident(table->sym->name), ident(p->sym->name));
9820	    }
9821	    else if(p->info.typ->type==Tarray) {
9822	      fprintf(fout,"\n\tif (!soap_in_%s(soap, tag, a->%s::%s, \"%s\"))", c_ident(p->info.typ), ident(table->sym->name), ident(p->sym->name), xsi_type(typ));
9823	    }
9824	    else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
9825	      fprintf(fout,"\n\tif (!(a->%s::%s).soap_in(soap, tag, \"%s\"))", ident(table->sym->name), ident(p->sym->name), xsi_type(typ));
9826	    }
9827	    else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
9828	      fprintf(fout,"\n\tif (!soap_in_%s(soap, tag, &(a->%s::%s), \"%s\"))", c_ident(p->info.typ), ident(table->sym->name), ident(p->sym->name), xsi_type(typ));
9829	    }
9830           fprintf(fout,"\n\t\treturn NULL;");
9831           if (has_getter(typ))
9832             fprintf(fout,"\n\tif (a->get(soap))\n\t\treturn NULL;");
9833           fprintf(fout,"\n\treturn a;\n}");
9834      }
9835      else
9836      {
9837        if (!is_invisible(typ->id->name))
9838        { fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, NULL))\n\t\treturn NULL;");
9839          fprintf(fout,"\n\ta = (%s)soap_class_id_enter(soap, soap->id, a, %s, sizeof(%s), soap->type, soap->arrayType);", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9840        }
9841        else
9842          fprintf(fout,"\n\ta = (%s)soap_class_id_enter(soap, \"\", a, %s, sizeof(%s), soap->type, soap->arrayType);", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
9843        fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
9844        fprintf(fout,"\n\tif (soap->alloced)");
9845        if (is_volatile(typ) || is_typedef(typ))
9846          fprintf(fout,"\n\t{\tsoap_default_%s(soap, a);",c_ident(typ));
9847        else
9848          fprintf(fout,"\n\t{\ta->soap_default(soap);");
9849        fprintf(fout,"\n\t\tif (soap->clist->type != %s)", soap_type(typ));
9850        fprintf(fout,"\n\t\t{\tsoap_revert(soap);");
9851        fprintf(fout,"\n\t\t\t*soap->id = '\\0';");
9852        if (is_volatile(typ) || is_typedef(typ))
9853          fprintf(fout,"\n\t\t\treturn soap_in_%s(soap, tag, a, type);", c_ident(typ));
9854        else
9855          fprintf(fout,"\n\t\t\treturn (%s)a->soap_in(soap, tag, type);", c_type_id(typ, "*"));
9856        fprintf(fout,"\n\t\t}\n\t}");
9857        table=(Table *)typ->ref;
9858        for (t = table; t; t = t->prev)
9859        { for (p = t->list; p; p = p->next)
9860	    if (p->info.sto & Sattribute)
9861              soap_attr_value(p, ptr_cast(t, "a"), ident(p->sym->name), ns_add(p->sym->name, nsa));
9862	}
9863        fflush(fout);
9864
9865      i=0;
9866    if (!is_discriminant(typ))
9867    { for (t = table; t; t = t->prev)
9868	i++;
9869      a=0;
9870      for (; i > 0; i--)
9871      { t = table;
9872	for (j = 0; j < i-1; j++)
9873	  t = t->prev;
9874	for (p = t->list; p; p = p->next)
9875	  { if (!(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ))
9876	    { if (is_anytype(p) || is_choice(p))
9877	        p = p->next;
9878		if (is_repetition(p))
9879	        { fprintf(fout,"\n\tstruct soap_blist *soap_blist_%s%d = NULL;", ident(p->next->sym->name), i);
9880		  p = p->next;
9881		}
9882		else
9883	          fprintf(fout,"\n\tsize_t soap_flag_%s%d = %ld;", ident(p->sym->name), i, p->info.maxOccurs);
9884	    }
9885	  }
9886      }
9887      if (a)
9888        fprintf(fout,";");
9889    }
9890      fflush(fout);
9891      if (!is_invisible(typ->id->name))
9892      { fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{");
9893        if (!is_discriminant(typ))
9894          fprintf(fout,"\n\t\tfor (;;)\n\t\t{\tsoap->error = SOAP_TAG_MISMATCH;");
9895      }
9896      else if (!is_discriminant(typ))
9897      { if (table->prev || table->list)
9898          fprintf(fout,"\n\t\tfor (short soap_flag = 0;; soap_flag = 1)\n\t\t{\tsoap->error = SOAP_TAG_MISMATCH;");
9899      }
9900      table=(Table *)typ->ref;
9901      a=0;
9902      i=0;
9903      for (t = table; t; t = t->prev)
9904	i++;
9905      for (; i > 0; i--)
9906      { t = table;
9907	for (j = 0; j < i-1; j++)
9908	  t = t->prev;
9909	for (p = t->list; p; p = p->next)
9910	{ if (is_item(p))
9911	    ;
9912	  else if (p->info.sto & (Sconst | Sprivate | Sprotected))
9913	    fprintf(fout, "\n\t\t\t/* non-serializable %s skipped */", ident(p->sym->name));
9914	  else if (is_transient(p->info.typ))
9915	    fprintf(fout, "\n\t\t\t/* transient %s skipped */", ident(p->sym->name));
9916	  else if (p->info.sto & Sattribute)
9917	    ;
9918	  else if (is_repetition(p))
9919	  {
9920              fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH && ");
9921	      if (is_unmatched(p->next->sym))
9922                fprintf(fout,"!soap_element_begin_in(soap, NULL, 1, NULL))");
9923	      else if (is_invisible(p->next->sym->name))
9924                fprintf(fout,"!soap_peek_element(soap))");
9925	      else
9926                fprintf(fout,"!soap_element_begin_in(soap, \"%s\", 1, NULL))", ns_add(p->next->sym->name, nse));
9927              fprintf(fout,"\n\t\t\t{\tif (a->%s::%s == NULL)\n\t\t\t\t{\tif (soap_blist_%s%d == NULL)\n\t\t\t\t\t\tsoap_blist_%s%d = soap_new_block(soap);\n\t\t\t\t\ta->%s::%s = (%s)soap_push_block(soap, soap_blist_%s%d, sizeof(%s));\n\t\t\t\t\tif (a->%s::%s == NULL)\n\t\t\t\t\t\treturn NULL;", ident(t->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), i, ident(p->next->sym->name), i, ident(t->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ), ident(p->next->sym->name), i, c_type(p->next->info.typ->ref), ident(t->sym->name), ident(p->next->sym->name));
9928              if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9929                fprintf(fout,"\n\t\t\t\t\t%s p;\n\t\t\t\t\tmemcpy(a->%s::%s, &p, sizeof(%s)); // a bit rough but portable", c_type(p->next->info.typ->ref), ident(t->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ->ref));
9930              if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
9931                fprintf(fout,"\n\t\t\t\t\ta->%s::%s->soap_default(soap);", ident(t->sym->name), ident(p->next->sym->name));
9932              else if (((Tnode*)p->next->info.typ->ref)->type != Tpointer  && !is_XML(p->next->info.typ->ref))
9933                fprintf(fout,"\n\t\t\t\t\tsoap_default_%s(soap, a->%s::%s);", c_ident(p->next->info.typ->ref), ident(t->sym->name), ident(p->next->sym->name));
9934              else
9935                fprintf(fout,"\n\t\t\t\t\t*a->%s::%s = NULL;", ident(t->sym->name), ident(p->next->sym->name));
9936              fprintf(fout,"\n\t\t\t\t}");
9937	      if (!is_invisible(p->next->sym->name))
9938                fprintf(fout,"soap_revert(soap);");
9939	      if (is_unmatched(p->next->sym))
9940	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9941                  fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, NULL, a->%s::%s))", ident(t->sym->name), ident(p->next->sym->name));
9942                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9943                  fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, NULL, a->%s::%s))", ident(t->sym->name), ident(p->next->sym->name));
9944                else
9945                  fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, a->%s::%s, \"%s\"))", c_ident(p->next->info.typ->ref), ident(t->sym->name), ident(p->next->sym->name), xsi_type(p->next->info.typ->ref));
9946	      }
9947	      else
9948	      { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9949                  fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", a->%s::%s))", ns_add(p->next->sym->name, nse), ident(t->sym->name), ident(p->next->sym->name));
9950                else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9951                  fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", a->%s::%s))", ns_add(p->next->sym->name, nse), ident(t->sym->name), ident(p->next->sym->name));
9952                else
9953                  fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s::%s, \"%s\"))", c_ident(p->next->info.typ->ref), ns_add(p->next->sym->name, nse), ident(t->sym->name), ident(p->next->sym->name), xsi_type(p->next->info.typ->ref));
9954	      }
9955              fprintf(fout,"\n\t\t\t\t{\ta->%s::%s++;\n\t\t\t\t\ta->%s::%s = NULL;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name));
9956	    /*
9957            fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)",ident(p->next->sym->name),i);
9958            if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_volatile(p->next->info.typ->ref))
9959              fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\t%s;\n\t\t\t\tq.soap_default(soap);\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"), c_type_id(p->next->info.typ->ref, "q"));
9960            else if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9961              fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\t%s;\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"), c_type_id(p->next->info.typ->ref, "q"));
9962            else
9963              fprintf(fout,"\n\t\t\t{\t%s;\n\t\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\t\treturn NULL;", c_type_id(p->next->info.typ, "p"));
9964	    if (is_unmatched(p->next->sym))
9965              fprintf(fout,"\n\t\t\t\tfor (a->%s::%s = 0; !soap_element_begin_in(soap, NULL, 1, NULL); a->%s::%s++)", ident(t->sym->name), ident(p->sym->name), ns_add_overridden(t, p->next, nse), ident(t->sym->name));
9966	    else if (is_invisible(p->next->sym->name))
9967              fprintf(fout,"\n\t\t\t\tfor (a->%s::%s = 0; !soap_peek_element(soap); a->%s::%s++)", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->sym->name));
9968	    else
9969              fprintf(fout,"\n\t\t\t\tfor (a->%s::%s = 0; !soap_element_begin_in(soap, \"%s\", 1, NULL); a->%s::%s++)", ident(t->sym->name), ident(p->sym->name), ns_add_overridden(t, p->next, nse), ident(t->sym->name), ident(p->sym->name));
9970            fprintf(fout,"\n\t\t\t\t{\tp = (%s)soap_push_block(soap, NULL, sizeof(%s));\n\t\t\t\t\tif (!p)\n\t\t\t\t\t\treturn NULL;", c_type(p->next->info.typ), c_type(p->next->info.typ->ref));
9971            if (((Tnode*)p->next->info.typ->ref)->type == Tclass || has_class(p->next->info.typ->ref))
9972              fprintf(fout,"\n\t\t\t\t\tmemcpy(p, &q, sizeof(%s));", c_type(p->next->info.typ->ref));
9973            if (((Tnode*)p->next->info.typ->ref)->type == Tclass && !is_external(p->next->info.typ->ref) && !is_volatile(p->next->info.typ->ref) && !is_typedef(p->next->info.typ->ref))
9974              fprintf(fout,"\n\t\t\t\t\tp->soap_default(soap);");
9975            else if (((Tnode*)p->next->info.typ->ref)->type != Tpointer  && !is_XML(p->next->info.typ->ref))
9976              fprintf(fout,"\n\t\t\t\t\tsoap_default_%s(soap, p);", c_ident(p->next->info.typ->ref));
9977            else
9978              fprintf(fout,"\n\t\t\t\t\t*p = NULL;");
9979	    if (!is_invisible(p->next->sym->name))
9980              fprintf(fout,"\n\t\t\t\t\tsoap_revert(soap);");
9981	    if (is_unmatched(p->next->sym))
9982            { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9983                fprintf(fout,"\n\t\t\t\t\tif (!soap_inliteral(soap, NULL, p))");
9984              else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9985                fprintf(fout,"\n\t\t\t\t\tif (!soap_inwliteral(soap, NULL, p))");
9986              else
9987                fprintf(fout,"\n\t\t\t\t\tif (!soap_in_%s(soap, NULL, p, \"%s\"))", c_ident(p->next->info.typ->ref), xsi_type(p->next->info.typ->ref));
9988	    }
9989	    else
9990            { if (is_XML(p->next->info.typ->ref) && is_string(p->next->info.typ->ref))
9991                fprintf(fout,"\n\t\t\t\t\tif (!soap_inliteral(soap, \"%s\", p))", ns_add_overridden(t, p->next, nse));
9992              else if (is_XML(p->next->info.typ->ref) && is_wstring(p->next->info.typ->ref))
9993                fprintf(fout,"\n\t\t\t\t\tif (!soap_inwliteral(soap, \"%s\", p))", ns_add_overridden(t, p->next, nse));
9994              else
9995                fprintf(fout,"\n\t\t\t\t\tif (!soap_in_%s(soap, \"%s\", p, \"%s\"))", c_ident(p->next->info.typ->ref), ns_add_overridden(t, p->next, nse), xsi_type(p->next->info.typ->ref));
9996	    }
9997            fprintf(fout,"\n\t\t\t\t\t\tbreak;");
9998            fprintf(fout,"\n\t\t\t\t\tsoap_flag_%s%d = 0;", ident(p->next->sym->name), i);
9999            fprintf(fout,"\n\t\t\t\t}");
10000            fprintf(fout,"\n\t\t\t\ta->%s::%s = (%s)soap_save_block(soap, NULL, NULL, 1);", ident(t->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ));
10001            fprintf(fout,"\n\t\t\t\tif (!soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)\n\t\t\t\t\tcontinue;\n\t\t\t}", ident(p->next->sym->name), i);
10002	  */
10003          p = p->next;
10004	  }
10005	  else if (is_anytype(p))
10006          { fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)", ident(p->next->sym->name), i);
10007	    fprintf(fout,"\n\t\t\t\tif ((a->%s::%s = soap_getelement(soap, &a->%s::%s)))", ident(t->sym->name), ident(p->next->sym->name), ident(t->sym->name), ident(p->sym->name));
10008	    fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s%d = 0;", ident(p->next->sym->name), i);
10009	    fprintf(fout,"\n\t\t\t\t\tcontinue;");
10010	    fprintf(fout,"\n\t\t\t\t}");
10011            p = p->next;
10012	  }
10013          else if (is_discriminant(typ) && p->next)
10014          { fprintf(fout,"\n\t\tif (!soap_in_%s(soap, &a->%s, &a->%s))", c_ident(p->next->info.typ), ident(p->sym->name), ident(p->next->sym->name));
10015            fprintf(fout,"\n\t\t\treturn NULL;");
10016	    i = 0;
10017            break;
10018	  }
10019	  else if (is_choice(p))
10020          { fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)",ident(p->next->sym->name),i);
10021	    fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, &a->%s::%s, &a->%s::%s))", c_ident(p->next->info.typ), ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name));
10022	    fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s%d = 0;", ident(p->next->sym->name), i);
10023	    fprintf(fout,"\n\t\t\t\t\tcontinue;");
10024	    fprintf(fout,"\n\t\t\t\t}");
10025            p = p->next;
10026	  }
10027	  else
10028	  {
10029	    if (!is_invisible(p->sym->name) && !is_primclass(typ) && p->info.typ->type != Tfun && !is_void(p->info.typ))
10030	   { if (is_string(p->info.typ) || is_wstring(p->info.typ) || is_stdstr(p->info.typ))
10031	       fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))",ident(p->sym->name), i);
10032             else if (is_template(p->info.typ))
10033	      fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
10034	     else
10035	       fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)",ident(p->sym->name), i);
10036	   }
10037	   if (is_unmatched(p->sym))
10038	   {
10039	    if (is_XML(p->info.typ) && is_string(p->info.typ)) {
10040	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, NULL, &(a->%s::%s)))", ident(t->sym->name), ident(p->sym->name));
10041	    } else if (is_XML(p->info.typ) && is_wstring(p->info.typ)) {
10042	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, NULL, &(a->%s::%s)))", ident(t->sym->name), ident(p->sym->name));
10043	    }
10044	    else if(p->info.typ->type==Tarray) {
10045	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, a->%s::%s, \"%s\"))", c_ident(p->info.typ),ident(t->sym->name),ident(p->sym->name),xsi_type(p->info.typ));
10046	    } else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
10047	      fprintf(fout,"\n\t\t\t\tif ((a->%s::%s).soap_in(soap, NULL, \"%s\"))", ident(t->sym->name),ident(p->sym->name),xsi_type(p->info.typ));
10048	    } else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
10049	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, NULL, &(a->%s::%s), \"%s\"))", c_ident(p->info.typ),ident(t->sym->name),ident(p->sym->name),xsi_type(p->info.typ));
10050	    }
10051           }
10052	   else if (!is_invisible(p->sym->name))
10053	   {
10054	    if (is_XML(p->info.typ) && is_string(p->info.typ)) {
10055	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", &(a->%s::%s)))", ns_add_overridden(t, p, nse), ident(t->sym->name),ident(p->sym->name));
10056	    } else if (is_XML(p->info.typ) && is_wstring(p->info.typ)) {
10057	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", &(a->%s::%s)))", ns_add_overridden(t, p, nse), ident(t->sym->name),ident(p->sym->name));
10058	    }
10059	    else if(p->info.typ->type==Tarray) {
10060	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s::%s, \"%s\"))", c_ident(p->info.typ),ns_add_overridden(t, p, nse),ident(t->sym->name),ident(p->sym->name),xsi_type(p->info.typ));
10061	    } else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
10062	      fprintf(fout,"\n\t\t\t\tif ((a->%s::%s).soap_in(soap, \"%s\", \"%s\"))", ident(t->sym->name),ident(p->sym->name),ns_add_overridden(t, p, nse),xsi_type(p->info.typ));
10063	    } else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
10064	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", &(a->%s::%s), \"%s\"))", c_ident(p->info.typ),ns_add_overridden(t, p, nse),ident(t->sym->name),ident(p->sym->name),xsi_type(p->info.typ));
10065	    }
10066           }
10067	    if (!is_invisible(p->sym->name) && !is_primclass(typ) && p->info.typ->type != Tfun && !is_void(p->info.typ))
10068	    { if (is_template(p->info.typ))
10069	        fprintf(fout,"\n\t\t\t\t\tcontinue;");
10070	      else
10071	      { fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s%d--;", ident(p->sym->name), i);
10072	        fprintf(fout,"\n\t\t\t\t\tcontinue;");
10073	        fprintf(fout,"\n\t\t\t\t}");
10074	      }
10075	    }
10076	    fflush(fout);
10077	  }
10078        }
10079      }
10080    if (!is_discriminant(typ))
10081    {
10082      i=0;
10083      for (t = table; t; t = t->prev)
10084	i++;
10085      for (; i > 0; i--)
10086      { t = table;
10087	for (j = 0; j < i-1; j++)
10088	  t = t->prev;
10089        for (p = t->list; p; p = p->next)
10090	  { if (is_repetition(p) || is_anytype(p) || is_choice(p))
10091	    { p = p->next;
10092	      continue;
10093	    }
10094	    if (is_invisible(p->sym->name)
10095	      && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !is_transient(p->info.typ) && !(p->info.sto & Sattribute))
10096	    { if (is_string(p->info.typ) || is_wstring(p->info.typ) || is_stdstr(p->info.typ))
10097	       fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))",ident(p->sym->name), i);
10098             else if (is_template(p->info.typ))
10099	       fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
10100             else
10101	       fprintf(fout,"\n\t\t\tif (soap_flag_%s%d && soap->error == SOAP_TAG_MISMATCH)",ident(p->sym->name), i);
10102	    if (is_XML(p->info.typ) && is_string(p->info.typ)) {
10103	      fprintf(fout,"\n\t\t\t\tif (soap_inliteral(soap, \"%s\", &(a->%s::%s)))", ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name));
10104	    } else if (is_XML(p->info.typ) && is_wstring(p->info.typ)) {
10105	      fprintf(fout,"\n\t\t\t\tif (soap_inwliteral(soap, \"%s\", &(a->%s::%s)))", ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name));
10106	    }
10107	    else if(p->info.typ->type==Tarray) {
10108	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", a->%s::%s, \"%s\"))", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name) ,xsi_type(p->info.typ));
10109	    } else if(p->info.typ->type==Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ)) {
10110	      fprintf(fout,"\n\t\t\t\tif ((a->%s::%s).soap_in(soap, \"%s\", \"%s\"))", ident(t->sym->name), ident(p->sym->name), ns_add_overridden(t, p, nse),xsi_type(p->info.typ));
10111	    } else if (p->info.typ->type != Tfun && !is_void(p->info.typ)) {
10112	      fprintf(fout,"\n\t\t\t\tif (soap_in_%s(soap, \"%s\", &(a->%s::%s), \"%s\"))", c_ident(p->info.typ),ns_add_overridden(t, p, nse), ident(t->sym->name), ident(p->sym->name) ,xsi_type(p->info.typ));
10113	    }
10114	   if (is_template(p->info.typ))
10115	      fprintf(fout,"\n\t\t\t\t\tcontinue;");
10116	   else
10117	   { fprintf(fout,"\n\t\t\t\t{\tsoap_flag_%s%d--;", ident(p->sym->name), i);
10118	     fprintf(fout,"\n\t\t\t\t\tcontinue;");
10119	     fprintf(fout,"\n\t\t\t\t}");
10120	   }
10121	  }
10122	 }
10123      }
10124      for (t = table; t; t = t->prev)
10125	for (p = t->list; p; p = p->next)
10126	  if (p->info.sto & Sreturn)
10127	    if (nse || has_ns_eq(NULL, p->sym->name))
10128	      fprintf(fout,"\n\t\t\tsoap_check_result(soap, \"%s\");", ns_add(p->sym->name, nse));
10129      if (!is_invisible(typ->id->name) || table->prev || table->list)
10130      { fprintf(fout,"\n\t\t\tif (soap->error == SOAP_TAG_MISMATCH)");
10131        if (!is_invisible(typ->id->name) || is_discriminant(typ))
10132          fprintf(fout,"\n\t\t\t\tsoap->error = soap_ignore_element(soap);");
10133        else
10134          fprintf(fout,"\n\t\t\tif (soap_flag)\n\t\t\t\t{\n\t\t\t\t\tsoap->error = SOAP_OK;\n\t\t\t\t\tbreak;\n\t\t\t\t}");
10135        fprintf(fout,"\n\t\t\tif (soap->error == SOAP_NO_TAG)");
10136        fprintf(fout,"\n\t\t\t\tbreak;");
10137        fprintf(fout,"\n\t\t\tif (soap->error)\n\t\t\t\treturn NULL;");
10138        fprintf(fout,"\n\t\t}");
10139      }
10140    }
10141    if (!is_discriminant(typ))
10142    { i=0;
10143      for (t = table; t; t = t->prev)
10144	i++;
10145      for (; i > 0; i--)
10146      { t = table;
10147	for (j = 0; j < i-1; j++)
10148	  t = t->prev;
10149	for (p = t->list; p; p = p->next)
10150	{   if (is_repetition(p))
10151	    { fprintf(fout, "\n\t\tif (a->%s::%s)\n\t\t\tsoap_pop_block(soap, soap_blist_%s%d);", ident(t->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), i);
10152	      fprintf(fout, "\n\t\tif (a->%s::%s)\n\t\t\ta->%s::%s = (%s)soap_save_block(soap, soap_blist_%s%d, NULL, 1);\n\t\telse\n\t\t{\ta->%s::%s = NULL;\n\t\t\tif (soap_blist_%s%d)\n\t\t\t\tsoap_end_block(soap, soap_blist_%s%d);\n\t\t}", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->next->sym->name), c_type(p->next->info.typ), ident(p->next->sym->name), i, ident(t->sym->name), ident(p->next->sym->name), ident(p->next->sym->name), i, ident(p->next->sym->name), i);
10153	      p = p->next;
10154	    }
10155	}
10156       }
10157      }
10158      if (has_getter(typ))
10159        fprintf(fout,"\n\t\tif (a->get(soap))\n\t\t\treturn NULL;");
10160      if (!is_invisible(typ->id->name))
10161      { fprintf(fout, "\n\t\tif (soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10162        fprintf(fout,"\n\t}\n\telse\n\t{");
10163        fprintf(fout,"\ta = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, soap_copy_%s);",c_type_id(typ, "*"), soap_type(typ), c_type(typ), c_ident(typ));
10164        fprintf(fout, "\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10165        fprintf(fout, "\n\t}");
10166      }
10167    if (!is_discriminant(typ))
10168    { a=0;
10169      i = 0;
10170      for (t = table; t; t = t->prev)
10171	i++;
10172      for (; i > 0; i--)
10173      { t = table;
10174	for (j = 0; j < i-1; j++)
10175	  t = t->prev;
10176	for (p = t->list; p; p = p->next)
10177	  { if (p->info.minOccurs > 0 && p->info.maxOccurs >= 0 && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ) && !is_repetition(p) && !is_choice(p) && p->info.hasval == False)
10178	    { if (is_item(p))
10179	        continue;
10180	      if (is_anytype(p))
10181	        p = p->next;
10182	      if (a==0)
10183	      { fprintf(fout,"\n\tif (%s(soap_flag_%s%d > %ld", strict_check(), ident(p->sym->name), i, p->info.maxOccurs - p->info.minOccurs);
10184	        a=1;
10185              }
10186	      else
10187	        fprintf(fout," || soap_flag_%s%d > %ld", ident(p->sym->name), i, p->info.maxOccurs - p->info.minOccurs);
10188	    }
10189	    else if (p->info.typ->minLength > 0 && !(p->info.sto & (Sconst | Sprivate | Sprotected)) && !(p->info.sto & Sattribute) && p->info.typ->type != Tfun && !is_void(p->info.typ) && !is_transient(p->info.typ) && !is_template(p->info.typ) && !is_repetition(p) && !is_choice(p) && p->info.hasval == False)
10190	    { if (is_item(p))
10191	        continue;
10192	      if (is_anytype(p))
10193	        p = p->next;
10194	      if (a==0)
10195	      { fprintf(fout,"\n\tif (%s(soap_flag_%s%d > 0", strict_check(), ident(p->sym->name), i);
10196	        a=1;
10197              }
10198	      else
10199	        fprintf(fout," || soap_flag_%s%d > 0", ident(p->sym->name), i);
10200	    }
10201	    else if (is_template(p->info.typ))
10202	    { if (p->info.minOccurs > 1)
10203	      { if (p->info.typ->type == Tpointer)
10204	        { if (a==0)
10205	          { fprintf(fout,"\n\tif (%s(!a->%s::%s || a->%s::%s->size() < %ld", strict_check(), ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10206	            a=1;
10207                  }
10208	          else
10209	            fprintf(fout," || !a->%s::%s || a->%s::%s->size() < %ld", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10210	        }
10211	        else
10212	        { if (a==0)
10213	          { fprintf(fout,"\n\tif (%s(a->%s::%s.size() < %ld", strict_check(), ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10214	            a=1;
10215                  }
10216	          else
10217	            fprintf(fout," || a->%s::%s.size() < %ld", ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10218	        }
10219	      }
10220	      if ( p->info.maxOccurs > 1)
10221	      { if (p->info.typ->type == Tpointer)
10222	        { if (a==0)
10223	          { fprintf(fout,"\n\tif (%s((a->%s::%s && a->%s::%s->size() > %ld)", strict_check(), ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10224	            a=1;
10225                  }
10226	          else
10227	            fprintf(fout," || (a->%s::%s && a->%s::%s->size() > %ld)", ident(t->sym->name), ident(p->sym->name), ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10228	        }
10229		else
10230	        { if (a==0)
10231	          { fprintf(fout,"\n\tif (%s(a->%s::%s.size() > %ld", strict_check(), ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10232	            a=1;
10233                  }
10234	          else
10235	            fprintf(fout," || a->%s::%s.size() > %ld", ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10236	        }
10237	      }
10238	    }
10239	    else if (is_repetition(p))
10240	    { if (p->info.minOccurs > 1)
10241	      { if (a==0)
10242	        { fprintf(fout,"\n\tif (%s(a->%s::%s < %ld", strict_check(), ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10243	          a=1;
10244                }
10245	        else
10246	          fprintf(fout," || a->%s::%s < %ld", ident(t->sym->name), ident(p->sym->name), p->info.minOccurs);
10247	      }
10248	      if (p->info.maxOccurs > 1)
10249	      { if (a==0)
10250	        { fprintf(fout,"\n\tif (%s(a->%s::%s > %ld", strict_check(), ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10251	          a=1;
10252                }
10253	        else
10254	          fprintf(fout," || a->%s::%s > %ld", ident(t->sym->name), ident(p->sym->name), p->info.maxOccurs);
10255	      }
10256	      p = p->next;
10257	    }
10258	    else if (is_choice(p))
10259	    { if (p->info.minOccurs != 0)
10260	      { if (a==0)
10261	        { fprintf(fout,"\n\tif (%s(soap_flag_%s%d", strict_check(), ident(p->next->sym->name), i);
10262	          a=1;
10263                }
10264	        else
10265	          fprintf(fout," || soap_flag_%s%d", ident(p->next->sym->name), i);
10266	      }
10267	      p = p->next;
10268	    }
10269	  }
10270       }
10271       if (a)
10272         fprintf(fout,"))\n\t{\tsoap->error = SOAP_OCCURS;\n\t\treturn NULL;\n\t}");
10273      }
10274      fprintf(fout,"\n\treturn a;\n}");
10275      }
10276
10277      break;
10278
10279    case Tunion:
10280      if (is_external(typ))
10281      { fprintf(fhead, "\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, int*, %s);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10282        return;
10283      }
10284      fprintf(fhead, "\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, int*, %s);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10285      fprintf(fout, "\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, int *choice, %s)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
10286      fprintf(fout, "\tsoap->error = SOAP_TAG_MISMATCH;");
10287      table = (Table *)typ->ref;
10288      for (p = table->list; p; p = p->next)
10289	{ if (p->info.sto & (Sconst | Sprivate | Sprotected))
10290	    fprintf(fout, "\n\t/* non-serializable %s skipped */", ident(p->sym->name));
10291	  else if (is_transient(p->info.typ))
10292	    fprintf(fout, "\n\t/* transient %s skipped */", ident(p->sym->name));
10293	  else if (p->info.sto & Sattribute)
10294	    ;
10295	  else if (is_repetition(p))
10296	    ;
10297	  else if (is_anytype(p))
10298	    ;
10299	  else if (!is_invisible(p->sym->name))
10300	  { if (is_unmatched(p->sym))
10301	    { if (is_XML(p->info.typ) && is_string(p->info.typ))
10302	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inliteral(soap, NULL, &a->%s))", ident(p->sym->name));
10303	      else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
10304	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inwliteral(soap, NULL, &a->%s))", ident(p->sym->name));
10305	      else if (p->info.typ->type == Tarray)
10306	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, NULL, a->%s, \"%s\"))", c_ident(p->info.typ),ident(p->sym->name),xsi_type(p->info.typ));
10307	      else if (p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
10308	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && a->%s.soap_in(soap, NULL, \"%s\"))", ident(p->sym->name), xsi_type(p->info.typ));
10309	      else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
10310	      { if (p->info.typ->type == Tpointer)
10311	          fprintf(fout, "\n\ta->%s = NULL;", ident(p->sym->name));
10312	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, NULL, &a->%s, \"%s\"))", c_ident(p->info.typ),ident(p->sym->name),xsi_type(p->info.typ));
10313	      }
10314	    }
10315	    else
10316	    { if (is_XML(p->info.typ) && is_string(p->info.typ))
10317	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
10318	      else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
10319	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inwliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
10320	      else if (p->info.typ->type == Tarray)
10321	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, \"%s\", a->%s, \"%s\"))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name),xsi_type(p->info.typ));
10322	      else if (p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
10323	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && a->%s.soap_in(soap, \"%s\", \"%s\"))", ident(p->sym->name),ns_add(p->sym->name, nse),xsi_type(p->info.typ));
10324	      else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
10325	      { if (p->info.typ->type == Tpointer)
10326	          fprintf(fout, "\n\ta->%s = NULL;", ident(p->sym->name));
10327	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, \"%s\", &a->%s, \"%s\"))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name),xsi_type(p->info.typ));
10328	      }
10329	    }
10330	    fprintf(fout, "\n\t{\t*choice = SOAP_UNION_%s_%s;", c_ident(typ), ident(p->sym->name));
10331	    fprintf(fout, "\n\t\treturn a;");
10332	    fprintf(fout, "\n\t}");
10333	    fflush(fout);
10334	  }
10335        }
10336      table = (Table *)typ->ref;
10337      for (p = table->list; p; p = p->next)
10338	{ if (p->info.sto & (Sconst | Sprivate | Sprotected))
10339	    ;
10340	  else if (is_transient(p->info.typ))
10341	    ;
10342	  else if (p->info.sto & Sattribute)
10343	    ;
10344	  else if (is_repetition(p))
10345	    ;
10346	  else if (is_anytype(p))
10347	    ;
10348	  else if (is_invisible(p->sym->name))
10349	  { if (is_XML(p->info.typ) && is_string(p->info.typ))
10350	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
10351	      else if (is_XML(p->info.typ) && is_wstring(p->info.typ))
10352	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_inwliteral(soap, \"%s\", &a->%s))", ns_add(p->sym->name, nse), ident(p->sym->name));
10353	      else if (p->info.typ->type == Tarray)
10354	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, \"%s\", a->%s, NULL))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name));
10355	      else if (p->info.typ->type == Tclass && !is_external(p->info.typ) && !is_volatile(p->info.typ) && !is_typedef(p->info.typ))
10356	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && a->%s.soap_in(soap, \"%s\", NULL))", ident(p->sym->name),ns_add(p->sym->name, nse));
10357	      else if (p->info.typ->type != Tfun && !is_void(p->info.typ))
10358	      { if (p->info.typ->type == Tpointer)
10359	          fprintf(fout, "\n\ta->%s = NULL;", ident(p->sym->name));
10360	        fprintf(fout, "\n\tif (soap->error == SOAP_TAG_MISMATCH && soap_in_%s(soap, \"%s\", &a->%s, NULL))", c_ident(p->info.typ),ns_add(p->sym->name, nse),ident(p->sym->name));
10361	      }
10362	    fprintf(fout, "\n\t{\t*choice = SOAP_UNION_%s_%s;", c_ident(typ), ident(p->sym->name));
10363	    fprintf(fout, "\n\t\treturn a;");
10364	    fprintf(fout, "\n\t}");
10365	    fflush(fout);
10366	  }
10367        }
10368      fprintf(fout, "\n\t*choice = 0;\n\tif (!soap->error)\n\t\tsoap->error = SOAP_TAG_MISMATCH;\n\treturn NULL;\n}");
10369      break;
10370
10371    case Tpointer:
10372
10373      if (is_external(typ))
10374      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10375        return;
10376      }
10377      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10378      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
10379      fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 1, NULL))");
10380      fprintf(fout,"\n\t\treturn NULL;");
10381
10382      if (is_template(typ))
10383      { fprintf(fout,"\n\tsoap_revert(soap);");
10384	fprintf(fout,"\n\tif (!a)\n\t\tif (!(a = (%s)soap_malloc(soap, sizeof(%s))))\n\t\t\treturn NULL;", c_type_id(typ, "*"), c_type(typ));
10385	fprintf(fout,"\n\tif (!(*a = soap_in_%s(soap, tag, *a, type)))\n\t\treturn NULL;", c_ident(typ->ref));
10386	fprintf(fout,"\n\treturn a;\n}");
10387      }
10388      else if(((Tnode *) typ->ref)->type == Tclass && !is_external(typ->ref) && !is_volatile(typ->ref) && !is_typedef(typ->ref))
10389      {
10390	fprintf(fout,"\n\tif (!a)\n\t\tif (!(a = (%s)soap_malloc(soap, sizeof(%s))))\n\t\t\treturn NULL;", c_type_id(typ, "*"), c_type(typ));
10391	fprintf(fout,"\n\t*a = NULL;\n\tif (!soap->null && *soap->href != '#')");
10392	fprintf(fout,"\n\t{\tsoap_revert(soap);");
10393	fprintf(fout, "\n\t\tif (!(*a = (%s)soap_instantiate_%s(soap, -1, soap->type, soap->arrayType, NULL)))", c_type(typ), c_ident(typ->ref));
10394	fprintf(fout, "\n\t\t\treturn NULL;");
10395	fprintf(fout, "\n\t\t(*a)->soap_default(soap);");
10396	fprintf(fout, "\n\t\tif (!(*a)->soap_in(soap, tag, NULL))");
10397	fprintf(fout, "\n\t\t\treturn NULL;");
10398	fprintf(fout,"\n\t}\n\telse\n\t{\t%s p = (%s)soap_id_lookup(soap, soap->href, (void**)a, %s, sizeof(%s), %d);", c_type_id(typ, "*"), c_type_id(typ, "*"), soap_type(typ->ref), c_type(typ->ref), reflevel(typ->ref) );
10399	if (((Tnode*)typ->ref)->type == Tclass)
10400	{ table = ((Tnode*)typ->ref)->ref;
10401	  for (p = classtable->list; p; p = p->next)
10402	  { if (p->info.typ->type == Tclass)
10403	    { Table *q = p->info.typ->ref;
10404	      if (q)
10405	        for (q = q->prev; q; q = q->prev)
10406                  if (q == table)
10407		    fprintf(fout, "\n\t\tif (!p && soap->error == SOAP_HREF)\n\t\t{\tsoap->error = SOAP_OK;\n\t\t\tp = (%s)soap_id_lookup(soap, soap->href, (void**)a, %s, sizeof(%s), 0);\n\t\t}", c_type_id(typ, "*"), soap_type(p->info.typ), c_type(p->info.typ));
10408	    }
10409          }
10410	}
10411	fprintf(fout,"\n\t\ta = p;");
10412	fprintf(fout,"\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10413	fprintf(fout,"\n\t}\n\treturn a;\n}");
10414      }
10415      else
10416      {
10417	fprintf(fout,"\n\tif (!a)\n\t\tif (!(a = (%s)soap_malloc(soap, sizeof(%s))))\n\t\t\treturn NULL;", c_type_id(typ, "*"), c_type(typ));
10418	fprintf(fout,"\n\t*a = NULL;\n\tif (!soap->null && *soap->href != '#')");
10419	fprintf(fout,"\n\t{\tsoap_revert(soap);");
10420	fprintf(fout,"\n\t\tif (!(*a = soap_in_%s(soap, tag, *a, type)))", c_ident(typ->ref));
10421	fprintf(fout,"\n\t\t\treturn NULL;");
10422
10423	fprintf(fout,"\n\t}\n\telse\n\t{\ta = (%s)soap_id_lookup(soap, soap->href, (void**)a, %s, sizeof(%s), %d);", c_type_id(typ, "*"), soap_type(typ->ref), c_type(typ->ref), reflevel(typ->ref) );
10424	fprintf(fout,"\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10425	fprintf(fout,"\n\t}\n\treturn a;\n}");
10426      }
10427
10428      break;
10429
10430    case Tarray:
10431      temp = typ;
10432      while(temp->type == Tarray){
10433	temp = temp->ref;
10434      }
10435      if (is_external(typ))
10436      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);",c_type_id(temp, "*"),c_ident(typ),c_type(typ));
10437        return;
10438      }
10439      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);",c_type_id(temp, "*"),c_ident(typ),c_type(typ));
10440      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{",c_type_id(temp, "*"),c_ident(typ),c_type_id(typ, "a"));
10441      fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, NULL))");
10442      fprintf(fout,"\n\t\treturn NULL;");
10443      fprintf(fout,"\n\tif (soap_match_array(soap, type))");
10444      fprintf(fout,"\n\t{\tsoap->error = SOAP_TYPE;\n\t\treturn NULL;\n\t}");
10445      fprintf(fout,"\n\ta = (%s)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL);", c_type_id(typ->ref, "(*)"), soap_type(typ), c_type(typ));
10446      fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
10447      fprintf(fout,"\n\tsoap_default_%s(soap, a);",c_ident(typ));
10448      fprintf(fout,"\n\tif (soap->body && !*soap->href)");
10449      total=get_dimension(typ);
10450      n=typ->ref;
10451      cardinality = 1;
10452      while(n->type==Tarray)
10453	{
10454	  total=total*get_dimension(n);
10455	  n = n->ref;
10456	  cardinality++;
10457	}
10458      fprintf(fout,"\n\t{\tint i;\n\t\tfor (i = 0; i < %d; i++)",get_dimension(typ));
10459  fprintf(fout,"\n\t\t{\tsoap_peek_element(soap);\n\t\t\tif (soap->position)\n\t\t\t{\ti = soap->positions[0];\n\t\t\t\tif (i < 0 || i >= %d)\n\t\t\t\t{\tsoap->error = SOAP_IOB;\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\t\t\t}", get_dimension(typ));
10460	fprintf(fout,"\n\t\t\tif (!soap_in_%s(soap, NULL, a", c_ident(typ->ref));
10461
10462      if(cardinality > 1){
10463	fprintf(fout,"[i]");
10464      }else {
10465	fprintf(fout,"+i");
10466      }
10467      fprintf(fout,", \"%s\"))", xsi_type(typ->ref));
10468      fprintf(fout,"\n\t\t\t{\tif (soap->error != SOAP_NO_TAG)\n\t\t\t\t\treturn NULL;");
10469      fprintf(fout,"\n\t\t\t\tsoap->error = SOAP_OK;");
10470      fprintf(fout,"\n\t\t\t\tbreak;");
10471      fprintf(fout,"\n\t\t\t}");
10472      fprintf(fout,"\n\t\t}");
10473      fprintf(fout,"\n\t\tif (soap->mode & SOAP_C_NOIOB)\n\t\t\twhile (soap_element_end_in(soap, tag) == SOAP_SYNTAX_ERROR)\n\t\t\t{\tsoap->peeked = 1;\n\t\t\t\tsoap_ignore_element(soap);\n\t\t\t}");
10474      fprintf(fout,"\n\t\telse if (soap_element_end_in(soap, tag))\n\t\t{\tif (soap->error == SOAP_SYNTAX_ERROR)\n\t\t\t\tsoap->error = SOAP_IOB;\n\t\t\treturn NULL;\n\t\t}");
10475      fprintf(fout,"\n\t}\n\telse\n\t{\ta = (%s)soap_id_forward(soap, soap->href, (void*)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL), 0, %s, 0, sizeof(%s), 0, NULL);", c_type_id(typ->ref, "(*)"), soap_type(typ), c_type(typ), soap_type(typ), c_type(typ));
10476      fprintf(fout,"\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10477      fprintf(fout,"\n\t}\n\treturn (%s)a;\n}", c_type_id(temp, "*"));
10478      break;
10479
10480    case Tenum:
10481      if (is_external(typ))
10482      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);",c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10483        return;
10484      }
10485      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);",c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10486      fprintf(fhead,"\n\nSOAP_FMAC3S int SOAP_FMAC4S soap_s2%s(struct soap*, const char*, %s);",c_ident(typ),c_type_id(typ, "*"));
10487      fprintf(fout,"\n\nSOAP_FMAC3S int SOAP_FMAC4S soap_s2%s(struct soap *soap, const char *s, %s)\n{",c_ident(typ),c_type_id(typ, "*a"));
10488      if (is_typedef(typ))
10489        fprintf(fout, "\n\treturn soap_s2%s(soap, s, a);\n}", t_ident(typ));
10490      else if (!is_mask(typ))
10491	{ fprintf(fout, "\n\tconst struct soap_code_map *map;");
10492          t = (Table*)typ->ref;
10493          if (t && t->list && has_ns_eq(NULL, ns_remove1(t->list->sym->name)))
10494	  { fprintf(fout, "\n\tchar *t;");
10495	    fprintf(fout, "\n\tif (!s)\n\t\treturn SOAP_OK;");
10496	    fprintf(fout, "\n\tsoap_s2QName(soap, s, &t);");
10497	    fprintf(fout, "\n\tmap = soap_code(soap_codes_%s, t);", c_ident(typ));
10498          }
10499          else
10500	  { fprintf(fout, "\n\tif (!s)\n\t\treturn SOAP_OK;");
10501	    fprintf(fout, "\n\tmap = soap_code(soap_codes_%s, s);", c_ident(typ));
10502	  }
10503	  m = 0;
10504          for (t = (Table*)typ->ref; t; t = t->prev)
10505            for (p = t->list; p; p = p->next)
10506	      if (p->info.val.i > m)
10507	        m = (unsigned long)p->info.val.i;
10508	  if (is_boolean(typ))
10509	    fprintf(fout, "\n\tif (map)\n\t\t*a = (%s)(map->code != 0);\n\telse\n\t{\tlong n;\n\t\tif (soap_s2long(soap, s, &n) || n < 0 || n > 1)\n\t\t\treturn soap->error = SOAP_TYPE;\n\t\t*a = (%s)(n != 0);\n\t}\n\treturn SOAP_OK;\n}", c_type(typ), c_type(typ));
10510	  else if (sflag)
10511	    fprintf(fout, "\n\tif (map)\n\t\t*a = (%s)map->code;\n\telse\n\t\treturn soap->error = SOAP_TYPE;\n\treturn SOAP_OK;\n}", c_type(typ));
10512          else
10513	    fprintf(fout, "\n\tif (map)\n\t\t*a = (%s)map->code;\n\telse\n\t{\tlong n;\n\t\tif (soap_s2long(soap, s, &n) || ((soap->mode & SOAP_XML_STRICT) && (n < 0 || n > %lu)))\n\t\t\treturn soap->error = SOAP_TYPE;\n\t\t*a = (%s)n;\n\t}\n\treturn SOAP_OK;\n}", c_type(typ), m, c_type(typ));
10514        }
10515	else
10516	{ t = (Table*)typ->ref;
10517          if (t && t->list && has_ns_eq(NULL, ns_remove1(t->list->sym->name)))
10518	  { fprintf(fout, "\n\tchar *t;");
10519	    fprintf(fout, "\n\tsoap_s2QName(soap, s, &t);");
10520	    fprintf(fout, "\n\t*a = (%s)soap_code_bits(soap_codes_%s, t);", c_type(typ), c_ident(typ));
10521          }
10522          else
10523	    fprintf(fout, "\n\t*a = (%s)soap_code_bits(soap_codes_%s, s);", c_type(typ), c_ident(typ));
10524	  fprintf(fout, "\n\treturn SOAP_OK;\n}");
10525	}
10526      fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{",c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
10527      if (is_boolean(typ))
10528      { fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, NULL))");
10529        fprintf(fout,"\n\t\treturn NULL;");
10530        fprintf(fout,"\n\tif (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, \":boolean\"))");
10531        fprintf(fout,"\n\t{\tsoap->error = SOAP_TYPE;\n\t\treturn NULL;\n\t}");
10532      }
10533      else if (typ->sym)
10534      { fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, NULL))");
10535        fprintf(fout,"\n\t\treturn NULL;");
10536        fprintf(fout,"\n\tif (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, \"%s\"))", base_type(typ, ""));
10537        fprintf(fout,"\n\t{\tsoap->error = SOAP_TYPE;\n\t\treturn NULL;\n\t}");
10538      }
10539      else
10540      { fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 0, type))");
10541        fprintf(fout,"\n\t\treturn NULL;");
10542      }
10543      fprintf(fout,"\n\ta = (%s)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL);", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
10544      fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
10545      fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{");
10546      fprintf(fout,"\tif (!a || soap_s2%s(soap, soap_value(soap), a) || soap_element_end_in(soap, tag))\n\t\t\treturn NULL;", c_ident(typ));
10547      fprintf(fout, "\n\t}\n\telse\n\t{\ta = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, NULL);", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
10548      fprintf(fout, "\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10549      fprintf(fout,"\n\t}\n\treturn a;\n}");
10550      break;
10551
10552    case Ttemplate:
10553      if (is_external(typ))
10554      { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10555        return;
10556      }
10557      fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10558      fprintf(fout, "\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)\n{", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
10559      n = typ->ref;
10560      fprintf(fout, "\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;");
10561      fprintf(fout, "\n\tif (!a && !(a = soap_new_%s(soap, -1)))\n\t\treturn NULL;", c_ident(typ));
10562      /* fprintf(fout, "\n\t%s::iterator i;\n\t;", c_type(typ)); */
10563      fprintf(fout, "\n\t%s;\n\tshort soap_flag = 0;", c_type_id(n, "n"));
10564      fprintf(fout, "\n\tdo");
10565      fprintf(fout, "\n\t{\tsoap_revert(soap);\n\t\t");
10566      if (n->type == Tpointer)
10567	fprintf(fout,"n = NULL;");
10568      else if (n->type == Tarray)
10569	fprintf(fout,"soap_default_%s(soap, &n);", c_ident(n));
10570      else if (n->type==Tclass && !is_external(n) && !is_volatile(n) && !is_typedef(n))
10571	fprintf(fout,"n.soap_default(soap);");
10572      else if (n->type != Tfun && !is_void(n) && !is_XML(n))
10573        fprintf(fout,"soap_default_%s(soap, &n);", c_ident(n));
10574      fprintf(fout, "\n\t\tif (*soap->id || *soap->href)");
10575      fprintf(fout, "\n\t\t{\tif (!soap_container_id_forward(soap, *soap->id?soap->id:soap->href, a, (size_t)a->size(), %s, %s, sizeof(%s), %d))\n\t\t\t\tbreak;\n\t\t\t", soap_type(reftype(n)), soap_type(typ), c_type(reftype(n)), reflevel(n));
10576      if (is_XML(n) && is_string(n))
10577        fprintf(fout, "if (!soap_inliteral(soap, tag, NULL))");
10578      else if (is_XML(n) && is_wstring(n))
10579        fprintf(fout, "if (!soap_inwliteral(soap, tag, NULL))");
10580      else if (n->type==Tarray)
10581        fprintf(fout, "if (!soap_in_%s(soap, tag, NULL, \"%s\"))", c_ident(n),xsi_type(n));
10582      else if (n->type != Tfun && !is_void(n))
10583        fprintf(fout, "if (!soap_in_%s(soap, tag, NULL, \"%s\"))", c_ident(n),xsi_type(n));
10584      fprintf(fout, "\n\t\t\t\tbreak;");
10585      fprintf(fout, "\n\t\t}\n\t\telse\n\t\t{");
10586      if (is_XML(n) && is_string(n))
10587        fprintf(fout, "\n\t\t\tif (!soap_inliteral(soap, tag, &n))");
10588      else if (is_XML(n) && is_wstring(n))
10589        fprintf(fout, "\n\t\t\tif (!soap_inwliteral(soap, tag, &n))");
10590      else if (n->type==Tarray)
10591        fprintf(fout, "\n\t\t\tif (!soap_in_%s(soap, tag, &n, \"%s\"))", c_ident(n),xsi_type(n));
10592      else if (n->type != Tfun && !is_void(n))
10593        fprintf(fout, "\n\t\t\tif (!soap_in_%s(soap, tag, &n, \"%s\"))", c_ident(n),xsi_type(n));
10594      fprintf(fout, "\n\t\t\t\tbreak;");
10595      if (!strcmp(typ->id->name, "std::vector") || !strcmp(typ->id->name, "std::deque"))
10596        fprintf(fout, "\n\t\t}\n\t\ta->push_back(n);\n\t\tsoap_flag = 1;");
10597      else
10598        fprintf(fout, "\n\t\t\ta->insert(a->end(), n);\n\t\t\tsoap_flag = 1;\n\t\t}");
10599      fprintf(fout, "\n\t}\n\twhile (tag && *tag != '-' && !soap_element_begin_in(soap, tag, 1, NULL));");
10600      fprintf(fout, "\n\tif (soap_flag && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))\n\t{\tsoap->error = SOAP_OK;\n\t\treturn a;\n\t}\n\treturn NULL;\n}");
10601      break;
10602    default: break;
10603    }
10604  fflush(fout);
10605}
10606
10607
10608void
10609soap_in_Darray(Tnode *typ)
10610{ int i, j, d;
10611  Entry *p, *q;
10612  Table *t, *table;
10613  char *nsa = ns_qualifiedAttribute(typ);
10614
10615  table=(Table *)typ->ref;
10616  q = table->list;
10617  p = is_dynamic_array(typ);
10618  d = get_Darraydims(typ);
10619
10620  if (is_external(typ))
10621  { fprintf(fhead,"\nSOAP_FMAC1 %s SOAP_FMAC2 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10622    return;
10623  }
10624  fprintf(fhead,"\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap*, const char*, %s, const char*);", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*"));
10625  if (typ->type == Tclass && !is_volatile(typ) && !is_typedef(typ))
10626  { fprintf(fout,"\n\nvoid *%s::soap_in(struct soap *soap, const char *tag, const char *type)", c_type(typ));
10627    fprintf(fout,"\n{\treturn soap_in_%s(soap, tag, this, type);\n}", c_ident(typ));
10628  }
10629  fflush(fout);
10630  fprintf(fout,"\n\nSOAP_FMAC3 %s SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, %s, const char *type)", c_type_id(typ, "*"),c_ident(typ),c_type_id(typ, "*a"));
10631  if ((has_ns(typ) || is_untyped(typ)) && is_binary(typ))
10632    fprintf(fout,"\n{");
10633  else if (d)
10634    fprintf(fout,"\n{\tint i, j, n;\n\t%s;", c_type_id(p->info.typ, "p"));
10635  else
10636    fprintf(fout,"\n{\tint i, j;\n\t%s;", c_type_id(p->info.typ, "p"));
10637  fprintf(fout,"\n\tif (soap_element_begin_in(soap, tag, 1, NULL))\n\t\treturn NULL;");
10638  if (has_ns(typ) || is_untyped(typ))
10639  { if (is_hexBinary(typ))
10640      fprintf(fout,"\n\tif (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, \":hexBinary\"))");
10641    else if (is_binary(typ))
10642      fprintf(fout,"\n\tif (*soap->type && soap_match_tag(soap, soap->type, type) && soap_match_tag(soap, soap->type, \":base64Binary\") && soap_match_tag(soap, soap->type, \":base64\"))");
10643    else
10644      fprintf(fout,"\n\tif (*soap->type && soap_match_array(soap, \"%s\") && soap_match_tag(soap, soap->type, type))", xsi_type(p->info.typ->ref));
10645  }
10646  else
10647    fprintf(fout,"\n\tif (soap_match_array(soap, type))");
10648  fprintf(fout,"\n\t{\tsoap->error = SOAP_TYPE;\n\t\treturn NULL;\n\t}");
10649  if (typ->type == Tclass)
10650  { fprintf(fout,"\n\ta = (%s)soap_class_id_enter(soap, soap->id, a, %s, sizeof(%s), soap->type, soap->arrayType);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
10651    fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
10652    fprintf(fout,"\n\tif (soap->alloced)\n\t\ta->soap_default(soap);");
10653    for (t = (Table*)typ->ref; t; t = t->prev)
10654    { for (p = t->list; p; p = p->next)
10655	if (p->info.sto & Sattribute)
10656          soap_attr_value(p, ptr_cast(t, "a"), ident(p->sym->name), ns_add(p->sym->name, nsa));
10657    }
10658  }
10659  else
10660  { fprintf(fout,"\n\ta = (%s)soap_id_enter(soap, soap->id, a, %s, sizeof(%s), 0, NULL, NULL, NULL);",c_type_id(typ, "*"), soap_type(typ), c_type(typ));
10661    fprintf(fout,"\n\tif (!a)\n\t\treturn NULL;");
10662    /*fprintf(fout,"\n\tif (soap->alloced)");*/
10663    fprintf(fout,"\n\tsoap_default_%s(soap, a);", c_ident(typ));
10664    for (t = (Table*)typ->ref; t; t = t->prev)
10665    { for (p = t->list; p; p = p->next)
10666	if (p->info.sto & Sattribute)
10667          soap_attr_value(p, "a", ident(p->sym->name), ns_add(p->sym->name, nsa));
10668    }
10669  }
10670  fprintf(fout,"\n\tif (soap->body && !*soap->href)\n\t{");
10671  p = is_dynamic_array(typ);
10672  if ((has_ns(typ) || is_untyped(typ)) && is_binary(typ))
10673  { if (is_hexBinary(typ))
10674      fprintf(fout,"\n\t\ta->__ptr = soap_gethex(soap, &a->__size);");
10675    else
10676    { fprintf(fout,"\n\t\ta->__ptr = soap_getbase64(soap, &a->__size, 0);");
10677      if (is_attachment(typ))
10678        fprintf(fout,"\n#ifndef WITH_LEANER\n\t\tif (soap_xop_forward(soap, &a->__ptr, &a->__size, &a->id, &a->type, &a->options))\n\t\t\treturn NULL;\n#endif");
10679    }
10680    fprintf(fout,"\n\t\tif ((!a->__ptr && soap->error) || soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10681  }
10682  else
10683  { if (d)
10684    { fprintf(fout,"\n\t\tn = soap_getsizes(soap->arraySize, a->__size, %d);", d);
10685      if (has_offset(typ))
10686        fprintf(fout,"\n\t\tn -= j = soap_getoffsets(soap->arrayOffset, a->__size, a->__offset, %d);", d);
10687      else
10688        fprintf(fout,"\n\t\tn -= j = soap_getoffsets(soap->arrayOffset, a->__size, NULL, %d);", d);
10689      if (p->info.minOccurs > 1)
10690        fprintf(fout,"\n\t\tif (%sn >= 0 && n < %ld)\n\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\treturn NULL;\n\t\t}", strict_check(), p->info.minOccurs);
10691      if (p->info.maxOccurs > 1)
10692        fprintf(fout,"\n\t\tif (%sn > %ld)\n\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\treturn NULL;\n\t\t}", strict_check(), p->info.maxOccurs);
10693      fprintf(fout,"\n\t\tif (n >= 0)");
10694      if (((Tnode*)p->info.typ->ref)->type == Tclass)
10695      { fprintf(fout,"\n\t\t{\ta->%s = soap_new_%s(soap, n);", ident(p->sym->name), c_ident(p->info.typ->ref));
10696        if (!is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
10697          fprintf(fout, "\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t\t(a->%s+i)->%s::soap_default(soap);", ident(p->sym->name), c_type(p->info.typ->ref));
10698        else if (((Tnode*)p->info.typ->ref)->type == Tpointer)
10699          fprintf(fout, "\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10700      }
10701      else if (has_class(p->info.typ->ref))
10702      { fprintf(fout,"\n\t\t{\ta->%s = soap_new_%s(soap, n);", ident(p->sym->name), c_ident(p->info.typ->ref));
10703        fprintf(fout, "\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10704      }
10705      else
10706      { fprintf(fout,"\n\t\t{\ta->%s = (%s)soap_malloc(soap, n*sizeof(%s));", ident(p->sym->name), c_type_id(p->info.typ->ref, "*"),  c_type(p->info.typ->ref));
10707        if (((Tnode*)p->info.typ->ref)->type == Tpointer)
10708          fprintf(fout, "\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t\ta->%s[i] = NULL;", ident(p->sym->name));
10709	else if (!is_XML(p->info.typ->ref))
10710          fprintf(fout, "\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10711      }
10712      fprintf(fout,"\n\t\t\tfor (i = 0; i < n; i++)");
10713      fprintf(fout,"\n\t\t\t{\tsoap_peek_element(soap);\n\t\t\t\tif (soap->position == %d)", d);
10714      fprintf(fout,"\n\t\t\t\t{\ti = ");
10715	for (i = 0; i < d; i++)
10716	{ fprintf(fout,"soap->positions[%d]", i);
10717	  for (j = 1; j < d-i; j++)
10718	    fprintf(fout,"*a->__size[%d]", j);
10719	  if (i < d-1)
10720	    fprintf(fout,"+");
10721	}
10722	fprintf(fout,"-j;");
10723	fprintf(fout,"\n\t\t\t\t\tif (i < 0 || i >= n)\n\t\t\t\t\t{\tsoap->error = SOAP_IOB;\n\t\t\t\t\t\treturn NULL;\n\t\t\t\t\t}\n\t\t\t\t}");
10724        fprintf(fout,"\n\t\t\t\tif (!soap_in_%s(soap, NULL, a->%s + i, \"%s\"))", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type(p->info.typ->ref));
10725      fprintf(fout,"\n\t\t\t\t{\tif (soap->error != SOAP_NO_TAG)\n\t\t\t\t\t\treturn NULL;");
10726      fprintf(fout,"\n\t\t\t\t\tsoap->error = SOAP_OK;");
10727      fprintf(fout,"\n\t\t\t\t\tbreak;");
10728      fprintf(fout,"\n\t\t\t\t}");
10729    }
10730    else
10731    { fprintf(fout,"\n\t\ta->__size = soap_getsize(soap->arraySize, soap->arrayOffset, &j);");
10732      if (has_offset(typ) && (p->next->next->info.sto & Sconst) == 0)
10733      { fprintf(fout,"\n\t\ta->__offset = j;");
10734      }
10735      if (p->info.minOccurs > 1)
10736        fprintf(fout,"\n\t\tif (%sa->__size >= 0 && a->__size < %ld)\n\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\treturn NULL;\n\t\t}", strict_check(), p->info.minOccurs);
10737      if (p->info.maxOccurs > 1)
10738        fprintf(fout,"\n\t\tif (%sa->__size > %ld)\n\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\treturn NULL;\n\t\t}", strict_check(), p->info.maxOccurs);
10739      fprintf(fout,"\n\t\tif (a->__size >= 0)");
10740      if (((Tnode*)p->info.typ->ref)->type == Tclass)
10741      { fprintf(fout,"\n\t\t{\ta->%s = soap_new_%s(soap, a->__size);", ident(p->sym->name), c_ident(p->info.typ->ref));
10742        if (!is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
10743          fprintf(fout, "\n\t\t\tfor (i = 0; i < a->__size; i++)\n\t\t\t\t(a->%s+i)->%s::soap_default(soap);", ident(p->sym->name), c_type(p->info.typ->ref));
10744        else
10745          fprintf(fout, "\n\t\t\tfor (i = 0; i < a->__size; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10746      }
10747      else if (has_class(p->info.typ->ref))
10748      { fprintf(fout,"\n\t\t{\ta->%s = soap_new_%s(soap, a->__size);", ident(p->sym->name), c_ident(p->info.typ->ref));
10749        fprintf(fout, "\n\t\t\tfor (i = 0; i < a->__size; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10750      }
10751      else
10752      { fprintf(fout,"\n\t\t{\ta->%s = (%s)soap_malloc(soap, sizeof(%s) * a->__size);", ident(p->sym->name), c_type_id(p->info.typ->ref, "*"),  c_type(p->info.typ->ref));
10753	if (((Tnode*)p->info.typ->ref)->type == Tpointer)
10754          fprintf(fout, "\n\t\t\tfor (i = 0; i < a->__size; i++)\n\t\t\t\ta->%s[i] = NULL;", ident(p->sym->name));
10755	else if (!is_XML(p->info.typ->ref))
10756          fprintf(fout, "\n\t\t\tfor (i = 0; i < a->__size; i++)\n\t\t\t\tsoap_default_%s(soap, a->%s+i);", c_ident(p->info.typ->ref), ident(p->sym->name));
10757      }
10758      fprintf(fout,"\n\t\t\tfor (i = 0; i < a->__size; i++)");
10759      fprintf(fout,"\n\t\t\t{\tsoap_peek_element(soap);\n\t\t\t\tif (soap->position)\n\t\t\t\t{\ti = soap->positions[0]-j;\n\t\t\t\t\tif (i < 0 || i >= a->__size)\n\t\t\t\t\t{\tsoap->error = SOAP_IOB;\n\t\t\t\t\t\treturn NULL;\n\t\t\t\t\t}\n\t\t\t\t}");
10760      if (is_XML(p->info.typ->ref) && is_string(p->info.typ->ref))
10761        fprintf(fout,"\n\t\t\t\tif (!soap_inliteral(soap, NULL, a->%s + i))", ident(p->sym->name));
10762      else if (is_XML(p->info.typ->ref) && is_wstring(p->info.typ->ref))
10763        fprintf(fout,"\n\t\t\t\tif (!soap_inwliteral(soap, NULL, a->%s + i))", ident(p->sym->name));
10764      else
10765        fprintf(fout,"\n\t\t\t\tif (!soap_in_%s(soap, NULL, a->%s + i, \"%s\"))", c_ident(p->info.typ->ref), ident(p->sym->name), xsi_type(p->info.typ->ref));
10766      fprintf(fout,"\n\t\t\t\t{\tif (soap->error != SOAP_NO_TAG)\n\t\t\t\t\t\treturn NULL;");
10767      fprintf(fout,"\n\t\t\t\t\tsoap->error = SOAP_OK;");
10768      fprintf(fout,"\n\t\t\t\t\tbreak;");
10769      fprintf(fout,"\n\t\t\t\t}");
10770    }
10771    fprintf(fout,"\n\t\t\t}\n\t\t}\n\t\telse");
10772    if (((Tnode*)p->info.typ->ref)->type == Tclass || has_class(p->info.typ->ref))
10773      fprintf(fout,"\n\t\t{\t%s;\n\t\t\tif (soap_new_block(soap) == NULL)\n\t\t\t\treturn NULL;", c_type_id(p->info.typ->ref, "q"));
10774    else
10775      fprintf(fout,"\n\t\t{\tif (soap_new_block(soap) == NULL)\n\t\t\t\treturn NULL;");
10776    if (p->info.maxOccurs > 1)
10777    { if (d)
10778        fprintf(fout,"\n\t\t\tfor (a->__size[0] = 0; a->__size[0] <= %ld; a->__size[0]++)", p->info.maxOccurs);
10779      else
10780        fprintf(fout,"\n\t\t\tfor (a->__size = 0; a->__size <= %ld; a->__size++)", p->info.maxOccurs);
10781    }
10782    else
10783    { if (d)
10784        fprintf(fout,"\n\t\t\tfor (a->__size[0] = 0; ; a->__size[0]++)");
10785      else
10786        fprintf(fout,"\n\t\t\tfor (a->__size = 0; ; a->__size++)");
10787    }
10788    fprintf(fout,"\n\t\t\t{\tp = (%s)soap_push_block(soap, NULL, sizeof(%s));\n\t\t\t\tif (!p)\n\t\t\t\t\treturn NULL;", c_type(p->info.typ), c_type(p->info.typ->ref));
10789    if (((Tnode*)p->info.typ->ref)->type == Tclass || has_class(p->info.typ->ref))
10790      fprintf(fout,"\n\t\t\t\tmemcpy(p, &q, sizeof(%s));", c_type(p->info.typ->ref));
10791    if (((Tnode*)p->info.typ->ref)->type == Tclass && !is_external(p->info.typ->ref) && !is_volatile(p->info.typ->ref) && !is_typedef(p->info.typ->ref))
10792      fprintf(fout,"\n\t\t\t\tp->soap_default(soap);");
10793    else if (((Tnode*)p->info.typ->ref)->type == Tpointer)
10794      fprintf(fout,"\n\t\t\t\t*p = NULL;");
10795    else if (!is_XML(p->info.typ->ref))
10796      fprintf(fout,"\n\t\t\t\tsoap_default_%s(soap, p);", c_ident(p->info.typ->ref));
10797    if (is_XML(p->info.typ->ref) && is_string(p->info.typ->ref))
10798      fprintf(fout,"\n\t\t\t\tif (!soap_inliteral(soap, NULL, p))");
10799    else if (is_XML(p->info.typ->ref) && is_wstring(p->info.typ->ref))
10800      fprintf(fout,"\n\t\t\t\tif (!soap_inwliteral(soap, NULL, p))");
10801    else
10802      fprintf(fout,"\n\t\t\t\tif (!soap_in_%s(soap, NULL, p, \"%s\"))", c_ident(p->info.typ->ref), xsi_type(p->info.typ->ref));
10803    fprintf(fout,"\n\t\t\t\t{\tif (soap->error != SOAP_NO_TAG)\n\t\t\t\t\t\treturn NULL;");
10804    fprintf(fout,"\n\t\t\t\t\tsoap->error = SOAP_OK;");
10805    fprintf(fout,"\n\t\t\t\t\tbreak;");
10806    fprintf(fout,"\n\t\t\t\t}");
10807    fprintf(fout,"\n\t\t\t}");
10808    fprintf(fout,"\n\t\t\tsoap_pop_block(soap, NULL);");
10809    if (p->info.minOccurs > 1)
10810      fprintf(fout,"\n\t\t\tif (%sa->__size < %ld)\n\t\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\t\treturn NULL;\n\t\t\t}", strict_check(), p->info.minOccurs);
10811    if (p->info.maxOccurs > 1)
10812      fprintf(fout,"\n\t\t\tif (%sa->__size > %ld)\n\t\t\t{\tsoap->error = SOAP_OCCURS;\n\t\t\t\treturn NULL;\n\t\t\t}", strict_check(), p->info.maxOccurs);
10813    if (((Tnode*)p->info.typ->ref)->type == Tclass || has_class(p->info.typ->ref))
10814      fprintf(fout,"\n\t\t\tif (soap->blist->size)\n\t\t\t\ta->%s = soap_new_%s(soap, soap->blist->size/sizeof(%s));\n\t\t\telse\n\t\t\t\ta->%s = NULL;", ident(p->sym->name), c_ident(p->info.typ->ref), c_type(p->info.typ->ref), ident(p->sym->name));
10815    else
10816      fprintf(fout,"\n\t\t\ta->%s = (%s)soap_malloc(soap, soap->blist->size);", ident(p->sym->name), c_type(p->info.typ));
10817    fprintf(fout,"\n\t\t\tsoap_save_block(soap, NULL, (char*)a->%s, 1);", ident(p->sym->name));
10818    fprintf(fout,"\n\t\t}");
10819    fprintf(fout,"\n\t\tif (soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10820  }
10821  if (has_getter(typ))
10822    fprintf(fout,"\n\t\tif (a->get(soap))\n\t\t\treturn NULL;");
10823  fprintf(fout,"\n\t}\n\telse\n\t{\t");
10824  if (is_attachment(typ))
10825    fprintf(fout,"\n#ifndef WITH_LEANER\n\t\tif (*soap->href != '#')\n\t\t{\tif (soap_dime_forward(soap, &a->__ptr, &a->__size, &a->id, &a->type, &a->options))\n\t\t\t\treturn NULL;\n\t\t}\n\t\telse\n#endif\n\t\t\t");
10826  if (typ->type == Tclass)
10827    fprintf(fout,"a = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, soap_copy_%s);", c_type_id(typ, "*"), soap_type(typ), c_type(typ), c_ident(typ));
10828  else
10829    fprintf(fout,"a = (%s)soap_id_forward(soap, soap->href, (void*)a, 0, %s, 0, sizeof(%s), 0, NULL);", c_type_id(typ, "*"), soap_type(typ), c_type(typ));
10830  fprintf(fout,"\n\t\tif (soap->body && soap_element_end_in(soap, tag))\n\t\t\treturn NULL;");
10831  fprintf(fout,"\n\t}");
10832  fprintf(fout,"\n\treturn a;\n}");
10833}
10834
10835const char *
10836cstring(const char *s)
10837{ size_t n;
10838  char *t;
10839  const char *r;
10840  for (n = 0, r = s; *r; n++, r++)
10841    if (*r == '"' || *r == '\\')
10842      n++;
10843    else if (*r < 32)
10844      n += 3;
10845  r = t = (char*)emalloc(n + 1);
10846  for (; *s; s++)
10847  { if (*s == '"' || *s == '\\')
10848    { *t++ = '\\';
10849      *t++ = *s;
10850    }
10851    else if (*s < 32)
10852    { sprintf(t, "\\%03o", (unsigned int)(unsigned char)*s);
10853      t += 4;
10854    }
10855    else
10856      *t++ = *s;
10857  }
10858  *t = '\0';
10859  return r;
10860}
10861
10862