1 /*
2 This file is part of adms - http://sourceforge.net/projects/mot-adms.
3 
4 adms is a code generator for the Verilog-AMS language.
5 
6 Copyright (C) 2002-2012 Laurent Lemaitre <r29173@users.sourceforge.net>
7               2014 Francesco Lannutti <nicolati@fastwebnet.it>
8               2013-2014 Guilherme Brondani Torri <guitorri@gmail.com>
9 
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23 
24 /* [nepasimprimer]
25  * RCS Info
26  * $Id: admsXml.c 1184 2010-06-23 21:33:17Z r29173 $
27  *
28  * Log
29  * $Log$
30  * Revision 1.12  2006/09/08 16:03:46  r29173
31  * set transform attributes as admsttext
32  *
33  * Revision 1.11  2006/08/30 02:57:12  r29173
34  * added %() support
35  *
36  * Revision 1.10  2006/08/18 17:10:50  r29173
37  * did lot of simplifications
38  * added element quark (character array)
39  *
40  * Revision 1.9  2006/08/10 11:31:47  r29173
41  * did lot of simplifications
42  *
43  * Revision 1.8  2006/08/04 17:15:31  r29173
44  * rearranged code partionning into files
45  *
46  * Revision 1.7  2006/08/02 16:45:52  r29173
47  * rearranged code partionning into files
48  *
49  * Revision 1.6  2005/04/25 12:29:33  r29173
50  * fixed few memory leak issues (introduced adms.._free)
51  *
52  * Revision 1.5  2004/11/19 12:29:56  r29173
53  * renamed _C into CAT
54  * saved argc, argv into admsmain element
55  * added adms:setenv transform
56  *
57  * Revision 1.4  2004/08/19 16:46:44  r29173
58  * cleaned-up i/o file handling
59  *
60  * Revision 1.3  2004/08/03 12:33:55  r29173
61  * import adms-1.21.0 from local CVS
62  *
63  * Revision 1.2  2004/05/26 13:02:47  r29173
64  * added default values to all enumerations
65  *
66  * Revision 1.1.1.1  2004/05/21 12:20:01  r29173
67  * recreated cvs data structure (crashed after revision 1.13.0!)
68  *
69  * Revision 1.67  2004/05/17 11:50:28  r29173
70  * simplified handling of variable attributes
71  *
72  * Revision 1.66  2004/05/13 07:34:50  r29173
73  * continue removing GNode* structure
74  *
75  * Revision 1.65  2004/05/05 10:19:30  r29173
76  * started removing GNode* structure
77  *
78  * Revision 1.64  2004/05/04 08:07:10  r29173
79  * added code for @final
80  * removed libltdl
81  *
82  * Revision 1.63  2004/04/19 16:24:31  r29173
83  * moved code of xparser to xmlParser
84  *
85  * Revision 1.62  2004/04/19 15:41:37  r29173
86  * moved code of treeValidate to xmlParser
87  *
88  * Revision 1.61  2004/04/19 14:52:19  r29173
89  * cleaned-up code
90  * added handling of \t in xml files
91  *
92  * Revision 1.60  2004/03/30 09:06:34  r29173
93  * added adms_message
94  * added statistics
95  * started noise implementation
96  *
97  * Revision 1.59  2004/03/25 20:14:49  r29173
98  * splitted variable->scope into small pieces
99  *
100  * Revision 1.58  2004/03/19 12:45:35  r29173
101  * started implementing code builder in yacc parser
102  *
103  * Revision 1.57  2004/03/19 10:24:58  r29173
104  * started implementing code builder in yacc parser
105  *
106  * Revision 1.56  2004/03/08 13:58:07  r29173
107  * all code lower-cased
108  *
109  * Revision 1.55  2004/03/08 08:24:20  r29173
110  * started implementing code builder in yacc parser
111  *
112  * Revision 1.54  2004/03/04 11:01:28  r29173
113  * started implementing code builder in yacc parser
114  *
115  * Revision 1.53  2004/03/02 13:42:00  r29173
116  * started implementing code builder in yacc parser
117  *
118  * Revision 1.52  2004/03/02 10:48:27  r29173
119  * start implementing support to new vla syntax
120  *
121  * Revision 1.51  2004/02/25 11:34:23  r29173
122  * start implementing support to new vla syntax
123  *
124  * Revision 1.50  2004/02/21 16:13:54  r29173
125  * start implementing support to new vla syntax
126  *
127  * Revision 1.49  2004/02/20 22:22:18  r29173
128  * start implementing support to new vla syntax
129  *
130  * Revision 1.48  2004/02/20 19:40:08  r29173
131  * start implementing support to new vla syntax
132  *
133  * Revision 1.47  2004/02/20 19:05:53  r29173
134  * start implementing support to new vla syntax
135  *
136  * Revision 1.46  2004/02/20 14:56:37  r29173
137  * start implementing support to new vla syntax
138  *
139  * Revision 1.45  2004/02/20 13:45:30  r29173
140  * start implementing support to new vla syntax
141  *
142  * Revision 1.44  2004/02/19 17:02:38  r29173
143  * started implementing code builder in yacc parser
144  *
145  * Revision 1.43  2004/02/19 01:25:11  r29173
146  * started implementing code builder in yacc parser
147  *
148  * Revision 1.42  2004/02/18 23:30:46  r29173
149  * started implementing code builder in yacc parser
150  *
151  * Revision 1.41  2004/02/18 00:43:01  r29173
152  * started implementing code builder in yacc parser
153  *
154  * Revision 1.40  2004/02/15 13:07:43  r29173
155  * started implementing code builder in yacc parser
156  *
157  * Revision 1.39  2004/02/14 22:46:49  r29173
158  * started implementing code builder in yacc parser
159  *
160  * Revision 1.38  2004/02/14 20:15:42  r29173
161  * started implementing code builder in yacc parser
162  *
163  * Revision 1.37  2004/02/13 14:28:39  r29173
164  * started implementing code builder in yacc parser
165  *
166  * Revision 1.36  2004/02/11 15:19:31  r29173
167  * release 1.5.1
168  *
169  * Revision 1.35  2004/02/11 14:20:11  r29173
170  * started implementing code builder in yacc parser
171  *
172  * Revision 1.34  2004/02/10 16:44:30  r29173
173  * started implementing code builder in yacc parser
174  *
175  * Revision 1.33  2004/02/10 10:48:24  r29173
176  * started implementing code builder in yacc parser
177  *
178  * Revision 1.32  2004/02/06 16:27:19  r29173
179  * started implementing code builder in yacc parser
180  *
181  * Revision 1.31  2004/02/06 14:52:08  r29173
182  * started implementing code builder in yacc parser
183  *
184  * Revision 1.30  2004/02/05 21:37:03  r29173
185  * started implementing code builder in yacc parser
186  *
187  * Revision 1.29  2004/02/05 14:02:30  r29173
188  * started implementing code builder in yacc parser
189  *
190  * Revision 1.28  2004/02/04 20:49:12  r29173
191  * started implementing code builder in yacc parser
192  *
193  * Revision 1.27  2004/02/04 20:34:24  r29173
194  * started implementing code builder in yacc parser
195  *
196  * Revision 1.26  2004/02/03 12:48:29  r29173
197  * started implementing code builder in yacc parser
198  *
199  * Revision 1.25  2004/01/29 15:49:08  r29173
200  * renamed accessors of xmlnodes
201  *
202  * Revision 1.24  2004/01/28 16:15:06  r29173
203  * started implementing code builder in yacc parser
204  *
205  * Revision 1.23  2004/01/28 10:37:29  r29173
206  * started implementing code builder in yacc parser
207  *
208  * Revision 1.22  2004/01/27 17:20:15  r29173
209  * started implementing code builder in yacc parser
210  *
211  * Revision 1.21  2004/01/27 13:46:14  r29173
212  * started implementing code builder in yacc parser
213  *
214  * Revision 1.20  2004/01/22 12:10:40  r29173
215  * started implementing code builder in yacc parser
216  *
217  * Revision 1.19  2004/01/21 14:35:45  r29173
218  * started implementing code builder in yacc parser
219  *
220  * Revision 1.18  2004/01/16 11:18:29  r29173
221  * removed use of adms_xml_load_scope
222  *
223  * Revision 1.17  2004/01/16 10:24:02  r29173
224  * added admsPreprocessor code
225  * added admsSimulator code
226  *
227  * Revision 1.16  2004/01/13 11:25:52  r29173
228  * added adms_message_usage
229  *
230  * Revision 1.15  2004/01/09 16:23:48  r29173
231  * cleaned-up use of #include
232  *
233  * Revision 1.14  2004/01/08 10:28:49  r29173
234  * moved code to always.[ch]
235  *
236  * Revision 1.13  2004/01/07 15:19:15  r29173
237  * added command line arguments -h and -v
238  *
239  * Revision 1.12  2004/01/06 12:35:01  r29173
240  * fixed the use of globals: input file and output file
241  *
242  * Revision 1.11  2004/01/05 11:40:14  r29173
243  * added message when no arg specified at command line
244  *
245  * Revision 1.10  2003/12/15 21:47:14  r29173
246  * started to create adms_object_new automatically
247  *
248  * Revision 1.9  2003/12/15 20:54:30  r29173
249  * started to create adms_object_new automatically
250  *
251  * Revision 1.8  2003/12/12 14:33:27  r29173
252  * changed construct (a!=NULL) into (a) or (a)?1:0
253  *
254  * Revision 1.7  2003/12/11 16:01:54  r29173
255  * changed prefix [epst]_adms_ to [epst]_
256  *
257  * Revision 1.6  2003/12/05 13:47:14  r29173
258  * used only one routine to create xml nodes
259  *
260  * Revision 1.5  2003/11/08 22:25:52  r29173
261  * re-organized code (removed file simulatorLoad.c)
262  *
263  * Revision 1.4  2003/11/08 17:46:10  r29173
264  * re-organized handling of xparsers
265  *
266  * Revision 1.3  2003/10/31 16:43:06  r29173
267  * clean-up the way xparser works
268  *
269  * Revision 1.2  2003/05/21 14:18:02  r29173
270  * add rcs info
271  *
272  */
273  /*[nepasimprimer]*/
274 #include "admstpathYacc.h"
275 typedef void (*p_valueto) (p_adms myadms1,p_adms myadms2);
276 typedef void (*p_valuetobasicenumeration) (p_adms myadms,admse myinteger);
277 typedef void (*p_valuetobasicinteger) (p_adms myadms,int myinteger);
278 typedef void (*p_valuetobasicreal) (p_adms myadms,double myreal);
279 typedef void (*p_valuetobasicstring) (p_adms myadms,char *mystring);
280 /* examples: /a/b => \0,a,b and a/b/ => a,b,\0*/
adms_split_new(const char * myname)281 static p_slist adms_split_new (const char* myname)
282 {
283   p_slist mypath=NULL;
284   const char* sj=myname;
285   const char* si=myname;
286   while(*sj!='\0')
287   {
288     if((*sj=='/')||(*sj=='\\'))
289     {
290       if(si==sj)
291         adms_slist_push(&mypath,NULL);
292       else
293         adms_slist_push(&mypath,(p_adms)adms_m2nclone(si,sj));
294       si=sj+1;
295     }
296     sj++;
297   }
298   adms_slist_push(&mypath,(p_adms)adms_m2nclone(si,sj));
299   return adms_slist_reverse(mypath);
300 }
free_strlist(p_slist myli0)301 static void free_strlist (p_slist myli0)
302 {
303   p_slist myli;
304   for(myli=myli0;myli;myli=myli->next)
305     free(myli->data);
306   adms_slist_free(myli0);
307 }
dirname(const char * myname)308 static char* dirname (const char* myname)
309 {
310   p_slist myli0=adms_split_new(myname);
311   char* mydirname=NULL;
312   p_slist myli=myli0;
313   int first=1;
314 #if defined(ADMS_OS_MS)
315   if((myli->data==NULL)&&myli->next&&(!strcmp((char*)(myli->next->data),"cygdrive")))
316   {
317     myli=myli->next->next;
318     if(myli)
319     {
320       adms_k2strconcat(&mydirname,(char*)(myli->data));
321       adms_k2strconcat(&mydirname,":/");
322       myli=myli->next;
323     }
324     else
325       adms_k2strconcat(&mydirname,ADMS_PATH_SEPARATOR);
326   }
327 #endif
328   for(;myli;myli=myli->next,first=0)
329   {
330     if(myli->data==NULL)
331       adms_k2strconcat(&mydirname,ADMS_PATH_SEPARATOR);
332     else if(myli->next==NULL)
333     {
334       if(!strcmp((char*)(myli->data),".")||!strcmp((char*)(myli->data),".."))
335       {
336         if(!first)
337           adms_k2strconcat(&mydirname,ADMS_PATH_SEPARATOR);
338         adms_k2strconcat(&mydirname,(char*)(myli->data));
339       }
340     }
341     else
342     {
343       adms_k2strconcat(&mydirname,(char*)(myli->data));
344       if(myli->next->next)
345         adms_k2strconcat(&mydirname,ADMS_PATH_SEPARATOR);
346     }
347   }
348   free_strlist(myli0);
349   if(mydirname)
350     return mydirname;
351   else
352     return adms_kclone(".");
353 }
basename(const char * myname)354 static char* basename (const char* myname)
355 {
356   p_slist myli0=adms_split_new(myname);
357   char* mybasename=NULL;
358   p_slist myli=adms_slist_last(myli0);
359   if(!(!strcmp((char*)(myli->data),".")||!strcmp((char*)(myli->data),"..")))
360     adms_k2strconcat(&mybasename,(char*)(myli->data));
361   free_strlist(myli0);
362   return mybasename;
363 }
filename(const char * myname)364 static char* filename (const char* myname)
365 {
366   char* myfilename=NULL;
367   char* mybasename=basename(myname);
368   adms_strconcat(&myfilename,dirname(myname));
369   if(mybasename)
370   {
371     adms_k2strconcat(&myfilename,ADMS_PATH_SEPARATOR);
372     adms_strconcat(&myfilename,mybasename);
373   }
374   return myfilename;
375 }
376 /*',,' becomes '' '' ''*/
377 /*'' becomes ''*/
378 /*'a\' 'b\' 'c' becomes 'a,b,c' - note: 'a\\' becomes 'a\' - strlen(delimiter) should be 1 */
adms_strsplit(const char * string,const char * delimiter,int max_tokens)379 static p_slist adms_strsplit (const char* string,const char* delimiter,int max_tokens)
380 {
381   p_slist myl=NULL;
382   p_slist myslash=NULL;
383   p_slist myli0=NULL;
384   p_slist myli;
385   const char* myrem=string;
386   char* occurence=strstr(myrem,delimiter);
387   int dlen=strlen(delimiter);
388   int stringlen=strlen(myrem);
389   while(--max_tokens && occurence)
390   {
391     int len=(int)(occurence-myrem);
392     char* str=adms_knclone(myrem,len);
393     adms_slist_push(&myli0,(p_adms)str);
394     myrem+=len+dlen;
395     if(!*myrem)
396       adms_slist_push(&myli0,(p_adms)adms_kclone(""));
397     occurence=strstr(myrem,delimiter);
398   }
399   if(*myrem)
400     adms_slist_push(&myli0,(p_adms)adms_knclone(myrem,stringlen-(int)(myrem-string)));
401   if(stringlen==0)
402     adms_slist_push(&myli0,(p_adms)adms_kclone(""));
403   adms_slist_inreverse(&myli0);
404   for(myli=myli0;myli;myli=myli->next)
405   {
406     char*s=(char*)(myli->data);
407     int mylength=strlen(s);
408     if(myli->next&&mylength&&(*(s+mylength-1)=='\\'))
409     {
410       *(s+mylength-1)=*delimiter;
411       if(!myslash)
412         myslash=myli;
413     }
414     else
415     {
416       if(myslash)
417       {
418         p_slist mylj;
419         char* myconcat=NULL;
420         for(mylj=myslash;mylj!=myli->next;mylj=mylj->next)
421           adms_strconcat(&myconcat,(char*)(mylj->data));
422         adms_slist_push(&myl,(p_adms)myconcat);
423         myslash=NULL;
424       }
425       else
426         adms_slist_push(&myl,myli->data);
427     }
428   }
429   adms_slist_free(myli0);
430   return adms_slist_reverse(myl);
431 }
adms_push_admst(p_admst myadmst,p_transform mytransform)432 static void adms_push_admst (p_admst myadmst,p_transform mytransform)
433 {
434   adms_slist_push(&root()->_valueof,(p_adms)myadmst);
435   adms_slist_push(&root()->_valueof,(p_adms)mytransform);
436   if(myadmst && myadmst->_refd) myadmst->_refd++;
437 }
438  /*[nepasimprimer]*/
awrite(p_transform mytransform,p_admst mylhs,p_admst myrhsori)439 static void awrite (p_transform mytransform,p_admst mylhs,p_admst myrhsori)
440 {
441   p_admst myrhs=aread(myrhsori);
442   if(mylhs->_pseudo==admse__croix)
443   {
444     ((p_attribute)mylhs->_item.p)->_value=(p_adms)myrhs;
445     if(myrhs) if(myrhs->_refd) myrhs->_refd++;
446   }
447   else if(!mylhs->_valueto)
448   {
449     adms_message_fatal_continue(("assignment not supported - lhs=%s rhs=%s\n",ns_etostr(mylhs->_pseudo),ns_etostr(myrhs->_pseudo)))
450     adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
451   }
452   else if(!myrhs)
453   {
454     ((p_valueto)mylhs->_valueto)(mylhs->_previous->_item.p,NULL);
455   }
456   else if(mylhs->_pseudo==admse_basicenumeration)
457   {
458     char* myvalues=aprintf(mytransform,myrhs);
459     admse mye=ns_strtoe(myvalues);
460     ((p_valuetobasicenumeration)mylhs->_valueto)(mylhs->_previous->_item.p,mye);
461     free(myvalues);
462   }
463   else if(mylhs->_pseudo==admse_basicinteger)
464   {
465     char* myvalues=aprintf(mytransform,myrhs);
466     int myi=adms_strtol(mytransform,myvalues);
467     ((p_valuetobasicinteger)mylhs->_valueto)(mylhs->_previous->_item.p,myi);
468     free(myvalues);
469   }
470   else if(mylhs->_pseudo==admse_basicreal)
471   {
472     char* myvalues=aprintf(mytransform,myrhs);
473     double myr=adms_strtod(mytransform,myvalues);
474     ((p_valuetobasicreal)mylhs->_valueto)(mylhs->_previous->_item.p,myr);
475     free(myvalues);
476   }
477   else if(mylhs->_pseudo==admse_basicstring)
478   {
479     char* myvalues=aprintf(mytransform,myrhs);
480     ((p_valuetobasicstring)mylhs->_valueto)(mylhs->_previous->_item.p,myvalues);
481   }
482   else if(mylhs->_pseudo==myrhs->_pseudo)
483     ((p_valueto)mylhs->_valueto)(mylhs->_previous->_item.p,myrhs->_item.p);
484   else if(mylhs->_pseudo==admse_empty)
485   {
486     if((myrhs->_pseudo==admse_basicenumeration)
487     ||(myrhs->_pseudo==admse_basicinteger)
488     ||(myrhs->_pseudo==admse_basicreal)
489     ||(myrhs->_pseudo==admse_basicstring))
490     {
491       adms_message_fatal_continue(("assigment not supported - lhs=empty rhs=%s\n",ns_etostr(myrhs->_pseudo)))
492       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
493     }
494     else
495       ((p_valueto)mylhs->_valueto)(mylhs->_previous->_item.p,myrhs->_item.p);
496   }
497   else if(mylhs->_pseudo!=admse_empty && myrhs->_pseudo!=admse_empty && mylhs->_pseudo!=myrhs->_pseudo)
498   {
499     /* SRW -- Changed this to a verbose message.  This gets triggered when
500     we replace a one-line conditional with a block, which must happen
501     if we add a line such as for contribution splitting.  Since the
502     operation is done below anyway, it shouldn't be considered as an
503     error.
504 
505     adms_message_error_continue(("mismatch in assigment - lhs=%s rhs=%s\n",ns_etostr(mylhs->_pseudo),ns_etostr(myrhs->_pseudo)))
506     adms_message_error(("see %s\n",adms_transform_uid(mytransform)))
507     */
508     adms_message_verbose(("mismatch in assigment - lhs=%s rhs=%s\n",ns_etostr(mylhs->_pseudo),ns_etostr(myrhs->_pseudo)))
509     adms_message_verbose(("see %s\n",adms_transform_uid(mytransform)))
510     ((p_valueto)mylhs->_valueto)(mylhs->_previous->_item.p,myrhs->_item.p);
511   }
512   else
513   {
514     ((p_valueto)mylhs->_valueto)(mylhs->_previous->_item.p,myrhs->_item.p);
515   }
516 }
postx(p_transform mytransform)517 static void postx (p_transform mytransform)
518 {
519   p_slist myli;
520   postxx(mytransform);
521   for(myli=mytransform->_templates;myli;myli=myli->next)
522     postx((p_transform)myli->data);
523   for(myli=mytransform->_children;myli;myli=myli->next)
524     postx((p_transform)myli->data);
525 }
526  /*[nepasimprimer]*/
getlist_from_argv(const int argc,const char ** argv,const char * opt,char * argtype)527 static p_slist getlist_from_argv (const int argc,const char* *argv,const char* opt,char* argtype)
528 {
529   p_slist mylist=NULL;
530   int i;
531   for(i=1;i<argc;i++)
532   {
533     char* myargvalue=NULL;
534     const char* value=argv[i];
535     if((strlen(value)==2)&&!strcmp(value,"-x"))
536       adms_message_verbose(("command option %s: ignored\n",value))
537     else if((strlen(value)==3)&&!strcmp(value,"-xv"))
538       adms_message_verbose(("command option %s: ignored\n",value))
539     else
540     {
541       if(!strcmp(opt,"-f"))
542       {
543         if((strlen(value)>2)&&(value[0]=='-'))
544         {}
545         else if((strlen(value)==2)&&(value[0]=='-'))
546           i++;
547         else
548           myargvalue=adms_kclone(argv[i]);
549       }
550       if(!strcmp(opt,value))
551       {
552         if(i<argc-1)
553           myargvalue=adms_kclone(argv[++i]);
554         else
555           adms_message_fatal(("option %s: no value found - expecting %s\n",opt,argtype))
556       }
557       else if((strlen(value)>2)&&!strncmp(opt,value,2))
558         myargvalue=adms_knclone(value+2,strlen(value)-2);
559       if(myargvalue)
560       {
561         char* myunixpath=filename(myargvalue);
562         free(myargvalue);
563         if(!strcmp(argtype,"file"))
564         {
565           if(!adms_file_isregular(myunixpath))
566             adms_message_fatal(("option %s: cannot read file '%s'\n",opt,myunixpath))
567         }
568         else if(!strcmp(argtype,"directory"))
569         {
570           if(!adms_file_isdirectory(myunixpath))
571             adms_message_fatal(("option %s: cannot read directory '%s'\n",opt,myunixpath))
572         }
573         adms_slist_push(&mylist,(p_adms)myunixpath);
574         adms_message_verbose(("shift: %s %s\n",opt,myunixpath))
575       }
576     }
577   }
578   return adms_slist_reverse(mylist);
579 }
580 #include "admsPreprocessor.h"
581 #include "admsVeriloga.h"
582  /*[nepasimprimer]*/
parseva(const int argc,const char ** argv,char * myverilogamsfile)583 static void parseva (const int argc,const char** argv,char* myverilogamsfile)
584 {
585   p_slist myli;
586   char* mytmpverilogamsfile=NULL;
587   adms_k2strconcat(&mytmpverilogamsfile,".");
588   adms_strconcat(&mytmpverilogamsfile,basename(myverilogamsfile));
589   adms_k2strconcat(&mytmpverilogamsfile,".adms");
590   root()->_filename=basename(myverilogamsfile);
591   root()->_fullfilename=adms_kclone(myverilogamsfile);
592   root()->_curfilename=adms_kclone(myverilogamsfile);
593   adms_message_info(("%sXml-%s (%s) %s %s\n",PACKAGE_NAME,PACKAGE_VERSION,GIT,__DATE__,__TIME__))
594   /* preprocess input file */
595   {
596     p_preprocessor mypreprocessor=(p_preprocessor)malloc(sizeof(t_preprocessor));
597     FILE* myverilogamsfilefh=adms_file_open_read(myverilogamsfile);
598     FILE* ofh=fopen(mytmpverilogamsfile,"wb");
599     if(!ofh)
600       adms_message_fatal(("%s: failed to open file [write mode]\n",mytmpverilogamsfile))
601     adms_preprocessor_setfile_input(myverilogamsfilefh);
602     mypreprocessor->cur_line_position=1;
603     mypreprocessor->cur_char_position=1;
604     mypreprocessor->cur_message=NULL;
605     mypreprocessor->fid=myverilogamsfilefh;
606     mypreprocessor->filename=adms_kclone(myverilogamsfile);
607     mypreprocessor->buffer=NULL;
608     mypreprocessor->cur_continuator_position=NULL;
609     adms_preprocessor_valueto_main((p_preprocessor_main)malloc(sizeof(t_preprocessor_main)));
610     pproot()->Defined=NULL;
611     pproot()->Scanner=NULL;
612     pproot()->Text=NULL;
613     pproot()->cr_filename=adms_kclone(myverilogamsfile);
614     pproot()->cr_scanner=mypreprocessor;
615     pproot()->error=0;
616     adms_slist_push(&pproot()->skipp_text,(p_adms)(long)(0));
617     pproot()->includePath=getlist_from_argv(argc,argv,"-I","directory");
618     adms_slist_push(&pproot()->includePath,(p_adms)".");
619 #ifdef ADMS_INCLUDEDIR
620     adms_slist_push(&pproot()->includePath,(p_adms)ADMS_INCLUDEDIR);
621 #endif
622     adms_preprocessor_get_define_from_argv(argc,argv);
623     adms_preprocessor_define_add_default("insideADMS");
624     adms_message_verbose(("create temporary file %s\n",mytmpverilogamsfile))
625     (int) preprocessorparse();
626     /* save preprocessed Verilog-AMS file */
627     fputs("# 1 \"",ofh);
628     fputs(pproot()->cr_scanner->filename,ofh);
629     fputs("\"\n",ofh);
630     adms_slist_inreverse(&pproot()->Text);
631     for(myli=pproot()->Text;myli;myli=myli->next)
632       fputs(((p_preprocessor_text)(myli->data))->_str,ofh);
633     fclose(ofh);
634     /* free preprocessor */
635     free(mypreprocessor->filename);
636     free(pproot()->cr_scanner);
637     fclose(myverilogamsfilefh);
638   }
639   /* parses temporary file */
640   {
641     FILE* ifh=adms_file_open_read(mytmpverilogamsfile);
642     if(root()->_dbg_vla==admse_yes)
643       adms_veriloga_setint_yydebug(1);
644     adms_veriloga_setfile_input(ifh);
645     if(verilogaparse(root()))
646       adms_message_fatal(("parse Verilog-AMS preprocessed file '%s' failed\n",mytmpverilogamsfile))
647     else
648       adms_message_verbose(("No error found during parsing\n"))
649     fclose(ifh);
650   }
651   for(myli=root()->_module;myli;myli=myli->next)
652     ((p_module)myli->data)->_evaluation=adms_evaluation_new();
653   free(mytmpverilogamsfile);
654   free(myverilogamsfile);
655 }
656  /*[nepasimprimer]*/
Xattribute(p_transform mytransform,p_admst dot,p_admst dotdot)657 static void Xattribute (p_transform mytransform,p_admst dot,p_admst dotdot)
658 {
659 }
Xnotadmst(p_transform mytransform,p_admst dot,p_admst dotdot)660 static void Xnotadmst (p_transform mytransform,p_admst dot,p_admst dotdot)
661 {
662   p_slist myli;
663   p_slist Attribute=mytransform->_attribute;
664   fputs("<",OUT());
665   fputs(mytransform->_name,OUT());
666   while(Attribute)
667   {
668     p_attribute myattribute=(p_attribute)Attribute->data;
669     char* value=tsprintf(dot,(p_text)myattribute->_value);
670     fputs(" ",OUT());
671     fputs(myattribute->_name,OUT());
672     fputs("=\"",OUT());
673     fputs(value,OUT());
674     free(value);
675     fputs("\"",OUT());
676     Attribute=Attribute->next;
677   }
678   for(myli=mytransform->_children;myli;myli=myli->next)
679   {
680     p_transform mychild=(p_transform)myli->data;
681     if(mychild->_callback==(void*)Xattribute)
682     {
683       char* name=tsprintf(dot,mychild->_textname);
684       fputs(" ",OUT());
685       fputs(name,OUT());
686       free(name);
687       fputs("=\"",OUT());
688       xtraverse(mychild->_children,dot,dotdot);
689       fputs("\"",OUT());
690     }
691   }
692   fputs(">\n",OUT());
693   xtraverse(mytransform->_children,dot,dotdot);
694   fputs("</",OUT());
695   fputs(mytransform->_name,OUT());
696   fputs(">\n",OUT());
697 }
698  /*[nepasimprimer]*/
699 static int myskipversion=0;
Xadmst(p_transform mytransform,p_admst dot,p_admst dotdot)700 static void Xadmst (p_transform mytransform,p_admst dot,p_admst dotdot)
701 {
702   if(!myskipversion&&mytransform->_textversion)
703   {
704     char* installed=PACKAGE_VERSION;
705     p_slist Installed=adms_strsplit(installed,".",3);
706     int installed_major=strtol((char*)(Installed->data),(char* *)NULL,10);
707     int installed_minor=strtol((char*)(Installed->next->data),(char* *)NULL,10);
708     char* requested=tsprintf(dot,mytransform->_textversion);
709     p_slist Requested=adms_strsplit(requested,".",3);
710     int xmlrequested_major;
711     int xmlrequested_minor;
712     if(!(Requested&&Requested->next&&Requested->next->next))
713       adms_message_fatal(("%s: invalid version number\n",adms_transform_uid(mytransform)))
714     errno=0;
715     xmlrequested_major=strtol((char*)(Requested->data),(char* *)NULL,10);
716     xmlrequested_minor=strtol((char*)(Requested->next->data),(char* *)NULL,10);
717     if(errno)
718     {
719       adms_message_fatal_continue(("'%s' invalid number - expecting for instance %s\n",requested,installed))
720       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
721     }
722     if((xmlrequested_major>installed_major)||(xmlrequested_major==installed_major && xmlrequested_minor>installed_minor))
723     {
724       adms_message_fatal_continue(("adms version too old (requested by xml control file: %s installed adms version: %s)\n",requested,installed))
725       adms_message_fatal_continue(("please install more recent version of adms\n"))
726       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
727     }
728     if((xmlrequested_major<installed_major)||(xmlrequested_major==installed_major && xmlrequested_minor<installed_minor))
729     {
730       adms_message_warning(("adms version too recent (requested by xml control file: %s installed adms version: %s)\n",requested,installed))
731       adms_message_warning(("please upgrade your xml control files or use other version of adms\n"))
732       adms_message_warning(("see %s\n",adms_transform_uid(mytransform)))
733     }
734     free(requested);
735     free_strlist(Installed);
736     free_strlist(Requested);
737   }
738   xtraverse(mytransform->_children,dot,dotdot);
739 }
740  /*[nepasimprimer]*/
Xforeach(p_transform mytransform,p_admst dot,p_admst dotdot)741 static void Xforeach (p_transform mytransform,p_admst dot,p_admst dotdot)
742 {
743   p_slist myli;
744   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
745   for(myli=pselect->_admst;myli;myli=myli->next)
746     xtraverse(mytransform->_children,(p_admst)myli->data,dot);
747   free_ptraverse(pselect);
748 }
Xjoin(p_transform mytransform,p_admst dot,p_admst dotdot)749 static void Xjoin (p_transform mytransform,p_admst dot,p_admst dotdot)
750 {
751   p_slist myli;
752   char* separator=(mytransform->_textseparator)?tsprintf(dot,mytransform->_textseparator):NULL;
753   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
754   for(myli=pselect->_admst;myli;myli=myli->next)
755   {
756     xtraverse(mytransform->_children,(p_admst)myli->data,dot);
757     if(myli->next&&separator)
758       fputs(separator,OUT());
759   }
760   free(separator);
761   free_ptraverse(pselect);
762 }
Xbreak(p_transform mytransform,p_admst dot,p_admst dotdot)763 static void Xbreak (p_transform mytransform,p_admst dot,p_admst dotdot)
764 {
765   break_found=1;
766 }
Xvalueof(p_transform mytransform,p_admst dot,p_admst dotdot)767 static void Xvalueof (p_transform mytransform,p_admst dot,p_admst dotdot)
768 {
769   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
770   if(pselect->_admst)
771   {
772     p_slist myli=pselect->_admst;
773     for(;myli;myli=myli->next)
774     {
775       p_admst myadmst=(p_admst)myli->data;
776       adms_push_admst(myadmst,mytransform);
777     }
778   }
779   else
780     adms_push_admst(NULL,mytransform);
781   free_ptraverse(pselect);
782 }
783  /*[nepasimprimer]*/
784 /*bug: if-inside behaves like if-not-inside when 'select' is not a $var*/
Find(p_slist l,p_kadms data)785 static int Find (p_slist l,p_kadms data)
786 {
787   while(l)
788   {
789     if(l->data==data)
790       return 1;
791     l=l->next;
792   }
793   return 0;
794 }
Xifinsidep_isempty(p_transform mytransform,p_admst dot,p_admst dotdot)795 static int Xifinsidep_isempty (p_transform mytransform,p_admst dot,p_admst dotdot)
796 {
797   p_admst mystackinto=adms_pull_admst(mytransform);
798   if(mystackinto)
799   {
800     if(mystackinto->_pseudo==admse_basiclist)
801     {
802       adms_message_fatal_continue(("'into' is a dollar variable - this is not supported\n"))
803       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
804     }
805     else if(mystackinto->_pseudo==admse__ladms)
806     {
807       p_slist into=(p_slist)mystackinto->_item.p;
808       p_ptraverse pselect=bar(dot,mytransform->_pathselect);
809       p_slist lselect;
810       for(lselect=pselect->_admst;lselect;lselect=lselect->next)
811       {
812         p_admst myadmst=(p_admst)lselect->data;
813         if(myadmst->_pseudo==admse_basiclist)
814         {
815           adms_message_fatal_continue(("'select' is a dollar variable - this is not supported\n"))
816           adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
817         }
818         else if(myadmst->_pseudo==admse__ladms)
819         {
820           p_slist mylii;
821           for(mylii=(p_slist)myadmst->_item.p;mylii;mylii=mylii->next)
822             if(!Find(into,mylii->data))
823             {
824               free_ptraverse(pselect);
825               deref(mystackinto);
826               return 0;
827             }
828         }
829         else
830           if(Find(into,myadmst->_item.p))
831           {
832             free_ptraverse(pselect);
833             deref(mystackinto);
834             return 0;
835           }
836       }
837       free_ptraverse(pselect);
838     }
839     deref(mystackinto);
840   }
841   return 1;
842 }
843  /*[nepasimprimer]*/
Xifinsidep(p_transform mytransform,p_admst dot,p_admst dotdot)844 static void Xifinsidep (p_transform mytransform,p_admst dot,p_admst dotdot)
845 {
846   if(!Xifinsidep_isempty(mytransform,dot,dotdot))
847     xtraverse(mytransform->_children,dot,dotdot);
848 }
Xifnotinsidep(p_transform mytransform,p_admst dot,p_admst dotdot)849 static void Xifnotinsidep (p_transform mytransform,p_admst dot,p_admst dotdot)
850 {
851   if(Xifinsidep_isempty(mytransform,dot,dotdot))
852     xtraverse(mytransform->_children,dot,dotdot);
853 }
854  /*[nepasimprimer]*/
Xifinsidepath_isempty(p_transform mytransform,p_admst dot,p_admst dotdot)855 static int Xifinsidepath_isempty (p_transform mytransform,p_admst dot,p_admst dotdot)
856 {
857   p_ptraverse plist=bar(dot,mytransform->_pathlist);
858   p_slist linto;
859   for(linto=plist->_admst;linto;linto=linto->next)
860   {
861     p_admst ainto=(p_admst)linto->data;
862     if(ainto->_pseudo==admse_basiclist)
863     {
864       adms_message_fatal_continue(("'into' is a dollar variable - this is not supported\n"))
865       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
866     }
867     else if(ainto->_pseudo==admse__ladms)
868     {
869       p_slist into=(p_slist)ainto->_item.p;
870       if(into)
871       {
872         p_ptraverse pselect=bar(dot,mytransform->_pathselect);
873         p_slist lselect;
874         for(lselect=pselect->_admst;lselect;lselect=lselect->next)
875         {
876           p_admst aselect=(p_admst)lselect->data;
877           if(aselect->_pseudo==admse_basiclist)
878           {
879             adms_message_fatal_continue(("'select' is a dollar variable - this is not supported\n"))
880             adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
881           }
882           else if(aselect->_pseudo==admse__ladms)
883           {
884             p_slist myli=(p_slist)aselect->_item.p;
885             for(;myli;myli=myli->next)
886               if(!Find(into,((p_admst)myli->data)->_item.p))
887               {
888                 free_ptraverse(pselect);
889                 free_ptraverse(plist);
890                 return 0;
891               }
892           }
893           else if(Find(into,aselect->_item.p))
894           {
895             free_ptraverse(pselect);
896             free_ptraverse(plist);
897             return 0;
898           }
899         }
900         free_ptraverse(pselect);
901       }
902     }
903   }
904   free_ptraverse(plist);
905   return 1;
906 }
Xifinsidepath(p_transform mytransform,p_admst dot,p_admst dotdot)907 static void Xifinsidepath (p_transform mytransform,p_admst dot,p_admst dotdot)
908 {
909   if(!Xifinsidepath_isempty(mytransform,dot,dotdot))
910     xtraverse(mytransform->_children,dot,dotdot);
911 }
Xifnotinsidepath(p_transform mytransform,p_admst dot,p_admst dotdot)912 static void Xifnotinsidepath (p_transform mytransform,p_admst dot,p_admst dotdot)
913 {
914   if(Xifinsidepath_isempty(mytransform,dot,dotdot))
915     xtraverse(mytransform->_children,dot,dotdot);
916 }
917  /*[nepasimprimer]*/
Xchoose(p_transform mytransform,p_admst dot,p_admst dotdot)918 static void Xchoose (p_transform mytransform,p_admst dot,p_admst dotdot)
919 {
920   p_slist myli;
921   for(myli=mytransform->_children;myli;myli=myli->next)
922   {
923     p_transform mychild=(p_transform)myli->data;
924     if(!strcmp(mychild->_name,"admst:when"))
925     {
926       p_ptraverse ptest=bar(dot,mychild->_pathtest);
927       if(ptest->_admst&&((p_admst)ptest->_admst->data)->_item.p)
928       {
929         xtraverse(mychild->_children,dot,dotdot);
930         free_ptraverse(ptest);
931         return;
932       }
933       free_ptraverse(ptest);
934     }
935     else if(!strcmp(mychild->_name,"admst:otherwise"))
936     {
937       xtraverse(mychild->_children,dot,dotdot);
938       return;
939     }
940     else
941       adms_message_fatal(("%s: %s admst transform unexpected",adms_transform_uid(mytransform),adms_transform_uid(mychild)))
942   }
943 }
944  /*[nepasimprimer]*/
Xif(p_transform mytransform,p_admst dot,p_admst dotdot)945 static void Xif (p_transform mytransform,p_admst dot,p_admst dotdot)
946 {
947   xtraverse(mytransform->_children,dot,dotdot);
948 }
949  /*[nepasimprimer]*/
Xreturn(p_transform mytransform,p_admst dot,p_admst dotdot)950 static void Xreturn (p_transform mytransform,p_admst dot,p_admst dotdot)
951 {
952   char* myname=tsprintf(dot,mytransform->_textname);
953   char* mystring=tsprintf(dot,mytransform->_textstring);
954   p_admst d=adms_admst_newpa(dot,dot,(p_adms)adms_return_new(myname,mystring));
955   d->_hasnewbasicstring=2;
956   free(myname);
957   free(mystring);
958   if(root()->_itransform)
959   {
960     d->_refd++;
961     adms_slist_push(&((p_itransform)root()->_itransform->data)->_return,(p_adms)d);
962     return;
963   }
964   adms_message_fatal_continue(("admst:return only allowed inside admst:template\n"))
965   adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
966 }
967  /*[nepasimprimer]*/
Xapplytemplates(p_transform mytransform,p_admst dot,p_admst dotdot)968 static void Xapplytemplates (p_transform mytransform,p_admst dot,p_admst dotdot)
969 {
970   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
971   p_slist myl0;
972   for(myl0=pselect->_admst;myl0;myl0=myl0->next)
973   {
974     p_slist myl1;
975     char* match=tsprintf((p_admst)myl0->data,mytransform->_textmatch);
976     p_itransform myitransform;
977     p_transform mytemplate=lookfortemplates(mytransform,match);
978     if(!mytemplate)
979     {
980       adms_message_fatal_continue(("Template not found:\n"))
981       adms_message_fatal_continue(("  <admst:template match=\"%s\"/>\n",match))
982       adms_message_fatal(("  see:  %s\n",adms_transform_uid(mytransform)))
983     }
984     free(match);
985     myitransform=adms_itransform_new(mytemplate);
986     myitransform->_originalcall=root()->_itransform?((p_itransform)root()->_itransform->data)->_originalcall:mytransform;
987     adms_slist_push(&root()->_itransform,(p_adms)myitransform);
988     if(((p_admst)myl0->data)->_item.p)
989     {
990       p_slist l;
991       xtraverse(mytemplate->_children,(p_admst)myl0->data,dot);
992       for(l=myitransform->_variable;l;l=l->next)
993       {
994         p_slist li;
995         for(li=((p_admstvariable)l->data)->_value;li;li=li->next)
996           deref((p_admst)li->data);
997         adms_admstvariable_free((p_admstvariable)l->data);
998       }
999     }
1000     adms_slist_pull(&root()->_itransform);
1001     adms_slist_push(&root()->_itransforminsideapplytemplate,(p_adms)myitransform);
1002     xtraverse(mytransform->_children,(p_admst)myl0->data,dot);
1003     break_found=0;
1004     for(myl1=myitransform->_return;myl1;myl1=myl1->next)
1005     {
1006       p_admst myadmst=(p_admst)myl1->data;
1007       myadmst->_refd--;
1008       if(myadmst->_refd==1)
1009       {
1010         adms_return_free((p_return)myadmst->_item.p);
1011         adms_admst_free(myadmst);
1012       }
1013     }
1014     adms_itransform_free(myitransform);
1015     adms_slist_pull(&root()->_itransforminsideapplytemplate);
1016   }
1017   free_ptraverse(pselect);
1018 }
1019  /*[nepasimprimer]*/
getdollar(p_transform mytransform,p_admst dot)1020 static p_admstvariable getdollar (p_transform mytransform,p_admst dot)
1021 {
1022   char* tname=tsprintf(dot,mytransform->_textname);
1023   p_admstvariable mydollar=lookup_dollar(tname);
1024   if(!mydollar)
1025   {
1026     mydollar=adms_admstvariable_new(tname);
1027     if(root()->_itransform)
1028     {
1029       p_itransform myitransform=(p_itransform)root()->_itransform->data;
1030       adms_slist_push(&myitransform->_variable,(p_adms)mydollar);
1031     }
1032     else
1033       adms_slist_push(&root()->_variable,(p_adms)mydollar);
1034   }
1035   free(tname);
1036   return mydollar;
1037 }
derefprevious(p_slist v)1038 static void derefprevious (p_slist v)
1039 {
1040   p_slist l;
1041   for(l=v;l;l=l->next)
1042   {
1043     ((p_admst)l->data)->_refd--;
1044     deref((p_admst)l->data);
1045   }
1046   adms_slist_free(v);
1047 }
getdollarnulled(p_transform mytransform,p_admst dot)1048 static p_admstvariable getdollarnulled (p_transform mytransform,p_admst dot)
1049 {
1050   p_admstvariable mydollar=getdollar(mytransform,dot);
1051   derefprevious(mydollar->_value);
1052   mydollar->_value=NULL;
1053   return mydollar;
1054 }
Xvariablenull(p_transform mytransform,p_admst dot,p_admst dotdot)1055 static void Xvariablenull (p_transform mytransform,p_admst dot,p_admst dotdot)
1056 {
1057   (void)getdollarnulled(mytransform,dot);
1058 }
Xvariablep(p_transform mytransform,p_admst dot,p_admst dotdot)1059 static void Xvariablep (p_transform mytransform,p_admst dot,p_admst dotdot)
1060 {
1061   adms_slist_push(&getdollarnulled(mytransform,dot)->_value,(p_adms)adms_pull_admst(mytransform));
1062 }
Xvariableconstant(p_transform mytransform,p_admst dot,p_admst dotdot)1063 static void Xvariableconstant (p_transform mytransform,p_admst dot,p_admst dotdot)
1064 {
1065   adms_slist_push(&getdollarnulled(mytransform,dot)->_value,mytransform->_textstring->_token->data);
1066 }
Xvariablestring(p_transform mytransform,p_admst dot,p_admst dotdot)1067 static void Xvariablestring (p_transform mytransform,p_admst dot,p_admst dotdot)
1068 {
1069   p_admstvariable mydollar=getdollar(mytransform,dot);
1070   p_slist mypreviousvalue=mydollar->_value;
1071   p_admst myadmst=adms_admst_newns(dot,dot,tsprintf(dot,mytransform->_textstring));
1072   mydollar->_value=NULL;
1073   adms_slist_push(&mydollar->_value,(p_adms)myadmst);
1074   if(myadmst->_refd) myadmst->_refd++;
1075   derefprevious(mypreviousvalue);
1076 }
Xvariable(p_transform mytransform,p_admst dot,p_admst dotdot)1077 static void Xvariable (p_transform mytransform,p_admst dot,p_admst dotdot)
1078 {
1079   p_slist l;
1080   p_slist ll;
1081   p_admstvariable mydollar=getdollar(mytransform,dot);
1082   p_slist mypreviousvalue=mydollar->_value;
1083   p_ptraverse ppath=bar(dot,mytransform->_pathpath);
1084   mydollar->_value=ppath->_admst;
1085   for(l=mydollar->_value;l;l=l->next)
1086   {
1087     if(((p_admst)l->data)->_refd)
1088      ((p_admst)l->data)->_refd++;
1089     if(((p_admst)l->data)->_hasnewbasicstring!=2)
1090       ((p_admst)l->data)->_refd++;
1091   }
1092   for(l=ppath->_alladmst;l;l=l->next)
1093     for(ll=(p_slist)l->data;ll;ll=ll->next)
1094       deref((p_admst)ll->data);
1095   for(l=ppath->_aliasadmst;l;l=l->next)
1096     deref((p_admst)l->data);
1097   for(l=ppath->_admst;l;l=l->next)
1098     deref((p_admst)l->data);
1099   adms_slist_free(ppath->_alladmst);
1100   adms_slist_free(ppath->_aliasadmst);
1101   free(ppath);
1102   derefprevious(mypreviousvalue);
1103 }
1104  /*[nepasimprimer]*/
Xvaluetop(p_transform mytransform,p_admst dot,p_admst dotdot)1105 static void Xvaluetop (p_transform mytransform,p_admst dot,p_admst dotdot)
1106 {
1107   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1108   p_slist myli;
1109   for(myli=pselect->_admst;myli;myli=myli->next)
1110     awrite(mytransform,(p_admst)myli->data,adms_pull_admst(mytransform));
1111   free_ptraverse(pselect);
1112 }
Xvaluetopath(p_transform mytransform,p_admst dot,p_admst dotdot)1113 static void Xvaluetopath (p_transform mytransform,p_admst dot,p_admst dotdot)
1114 {
1115   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1116   p_ptraverse ptstring=bar(dot,(p_path)mytransform->_textstring->_token->data);
1117   p_slist myli=pselect->_admst;
1118   p_slist mylii=ptstring->_admst;
1119   for(;myli&&mylii;myli=myli->next,mylii=mylii->next?mylii->next:mylii)
1120     awrite(mytransform,(p_admst)myli->data,(p_admst)mylii->data);
1121   free_ptraverse(ptstring);
1122   free_ptraverse(pselect);
1123 }
Xvaluetonull(p_transform mytransform,p_admst dot,p_admst dotdot)1124 static void Xvaluetonull (p_transform mytransform,p_admst dot,p_admst dotdot)
1125 {
1126   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1127   p_slist myli=pselect->_admst;
1128   for(;myli;myli=myli->next)
1129   {
1130     p_admst myadmst=(p_admst)myli->data;
1131     if(myadmst->_pseudo==admse_basiclist)
1132       ((p_admstvariable)myadmst->_item.p)->_value=NULL;
1133     else if(myadmst->_pseudo==admse__ladms || myadmst->_pseudo==admse__ladmst)
1134       awrite(mytransform,(p_admst)myli->data,NULL);
1135     else if(myadmst->_pseudo==admse__croix)
1136     {
1137       p_attribute myattribute=(p_attribute)myadmst->_item.p;
1138       myattribute->_value=NULL;
1139     }
1140   }
1141   free_ptraverse(pselect);
1142 }
Xvaluetoconstant(p_transform mytransform,p_admst dot,p_admst dotdot)1143 static void Xvaluetoconstant (p_transform mytransform,p_admst dot,p_admst dotdot)
1144 {
1145   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1146   p_slist myli;
1147   p_admst myconstant=(p_admst)mytransform->_textstring->_token->data;
1148   for(myli=pselect->_admst;myli;myli=myli->next)
1149     awrite(mytransform,(p_admst)myli->data,myconstant);
1150   free_ptraverse(pselect);
1151 }
Xvaluetostring(p_transform mytransform,p_admst dot,p_admst dotdot)1152 static void Xvaluetostring (p_transform mytransform,p_admst dot,p_admst dotdot)
1153 {
1154   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1155   p_slist l;
1156   char* tvalue=tsprintf(dot,mytransform->_textstring);
1157   p_admst myadmst=adms_admst_newns(dot,dot,tvalue);
1158   for(l=pselect->_admst;l;l=l->next)
1159     awrite(mytransform,(p_admst)l->data,myadmst);
1160   deref(myadmst);
1161   free_ptraverse(pselect);
1162 }
Xvalueto(p_transform mytransform,p_admst dot,p_admst dotdot)1163 static void Xvalueto (p_transform mytransform,p_admst dot,p_admst dotdot)
1164 {
1165   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1166   p_ptraverse ppath=bar(dot,mytransform->_pathpath);
1167   p_slist myli;
1168   p_slist mylii=ppath->_admst;
1169   if(mylii)
1170     for(myli=pselect->_admst;myli;myli=myli->next,mylii=mylii->next?mylii->next:mylii)
1171       awrite(mytransform,(p_admst)myli->data,(p_admst)mylii->data);
1172   else
1173     for(myli=pselect->_admst;myli;myli=myli->next)
1174       awrite(mytransform,(p_admst)myli->data,NULL);
1175   free_ptraverse(ppath);
1176   free_ptraverse(pselect);
1177 }
1178 
1179  /*[nepasimprimer]*/
Xtext(p_transform mytransform,p_admst dot,p_admst dotdot)1180 static void Xtext (p_transform mytransform,p_admst dot,p_admst dotdot)
1181 {
1182   if(mytransform->_textformat==NULL)
1183     return;
1184   if(mytransform->_pathselect)
1185   {
1186     p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1187     p_slist myli;
1188     for(myli=pselect->_admst;myli;myli=myli->next)
1189       tprintf((p_admst)myli->data,mytransform->_textformat);
1190     free_ptraverse(pselect);
1191   }
1192   else
1193     tprintf(dot,mytransform->_textformat);
1194 }
1195  /*[nepasimprimer]*/
Xmessage(p_transform mytransform,p_admst dot,p_admst dotdot)1196 static void Xmessage (p_transform mytransform,p_admst dot,p_admst dotdot)
1197 {
1198   if(mytransform->_pathselect)
1199   {
1200     p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1201     p_slist myli;
1202     for(myli=pselect->_admst;myli;myli=myli->next)
1203     {
1204       char* text=tsprintf((p_admst)myli->data,mytransform->_textformat);
1205       adms_message_info(("%s",text))
1206       free(text);
1207     }
1208     free_ptraverse(pselect);
1209   }
1210   else
1211   {
1212     char* text=tsprintf(dot,mytransform->_textformat);
1213     adms_message_info(("%s",text))
1214     free(text);
1215   }
1216 }
Xwarning(p_transform mytransform,p_admst dot,p_admst dotdot)1217 static void Xwarning (p_transform mytransform,p_admst dot,p_admst dotdot)
1218 {
1219   if(mytransform->_pathselect)
1220   {
1221     p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1222     p_slist myli;
1223     for(myli=pselect->_admst;myli;myli=myli->next)
1224     {
1225       char* text=tsprintf((p_admst)myli->data,mytransform->_textformat);
1226       adms_message_warning(("%s",text))
1227       free(text);
1228     }
1229     free_ptraverse(pselect);
1230   }
1231   else
1232   {
1233     char* text=tsprintf(dot,mytransform->_textformat);
1234     adms_message_warning(("%s",text))
1235     free(text);
1236   }
1237 }
Xerror(p_transform mytransform,p_admst dot,p_admst dotdot)1238 static void Xerror (p_transform mytransform,p_admst dot,p_admst dotdot)
1239 {
1240   if(mytransform->_pathselect)
1241   {
1242     p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1243     p_slist myli;
1244     for(myli=pselect->_admst;myli;myli=myli->next)
1245     {
1246       char* text=tsprintf((p_admst)myli->data,mytransform->_textformat);
1247       adms_message_error(("%s",text))
1248       free(text);
1249     }
1250     free_ptraverse(pselect);
1251   }
1252   else
1253   {
1254     char* text=tsprintf(dot,mytransform->_textformat);
1255     adms_message_error(("%s",text))
1256     free(text);
1257   }
1258 }
Xfatal(p_transform mytransform,p_admst dot,p_admst dotdot)1259 static void Xfatal (p_transform mytransform,p_admst dot,p_admst dotdot)
1260 {
1261   if(mytransform->_pathselect)
1262   {
1263     p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1264     p_slist myli;
1265     for(myli=pselect->_admst;myli;myli=myli->next)
1266     {
1267       char* text=tsprintf((p_admst)myli->data,mytransform->_textformat);
1268       adms_message_fatal_continue(("%s",text))
1269       free(text);
1270     }
1271     adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
1272     free_ptraverse(pselect);
1273   }
1274   else
1275   {
1276     char* text=tsprintf(dot,mytransform->_textformat);
1277     adms_message_fatal_continue(("%s",text))
1278     adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
1279     free(text);
1280   }
1281 }
1282  /*[nepasimprimer]*/
Xnewarguments(p_transform mytransform,p_admst dot,p_admst dotdot)1283 static void Xnewarguments (p_transform mytransform,p_admst dot,p_admst dotdot)
1284 {
1285   p_admst myadmst;
1286   int size=adms_slist_length(mytransform->_textarguments);
1287   p_slist* Arguments=(p_slist*)calloc(size,sizeof(p_admst));
1288   char* tdatatype=tsprintf(dot,mytransform->_textdatatype);
1289   p_new new=!strcmp(tdatatype,"quark")?adms_admsxml_new(mytransform,"basicstring"):adms_admsxml_new(mytransform,tdatatype);
1290   int i=0;
1291   p_slist myli;
1292   free(tdatatype);
1293   for(myli=mytransform->_textarguments;myli;myli=myli->next)
1294   {
1295     p_text myargname=(p_text)myli->data;
1296     if(myargname->_admse==admse__path)
1297     {
1298       p_ptraverse myptraverse=bar(dot,(p_path)myargname->_token->data);
1299       Arguments[i]=myptraverse->_admst;
1300       adms_slist_free(myptraverse->_alladmst);
1301       free(myptraverse);
1302     }
1303     else if(myargname->_admse==admse__p)
1304     {
1305       Arguments[i]=NULL;
1306       adms_slist_push(&Arguments[i],(p_adms)adms_pull_admst(mytransform));
1307     }
1308     else
1309     {
1310       p_admst mynewadmst=adms_admst_newns(dot,dot,tsprintf(dot,myargname));
1311       Arguments[i]=NULL;
1312       adms_slist_push(&Arguments[i],(p_adms)mynewadmst);
1313     }
1314     i++;
1315   }
1316   myadmst=new(mytransform,dot,Arguments,size);
1317   xtraverse(mytransform->_children,myadmst,dot);
1318   deref(myadmst);
1319   free(Arguments);
1320 }
Xnew(p_transform mytransform,p_admst dot,p_admst dotdot)1321 static void Xnew (p_transform mytransform,p_admst dot,p_admst dotdot)
1322 {
1323   p_admst myadmst;
1324   int size=mytransform->_pathinputs?adms_slist_length(mytransform->_pathinputs):1;
1325   p_slist* inputs=(p_slist*)calloc(size,sizeof(p_admst));
1326   p_ptraverse* ptraverseinputs=(p_ptraverse*)calloc(size,sizeof(p_ptraverse));
1327   char* tdatatype=tsprintf(dot,mytransform->_textdatatype);
1328   p_new new=!strcmp(tdatatype,"quark")?adms_admsxml_new(mytransform,"basicstring"):adms_admsxml_new(mytransform,tdatatype);
1329   int i=0;
1330   p_slist myli;
1331   free(tdatatype);
1332   for(myli=mytransform->_pathinputs;myli;myli=myli->next)
1333   {
1334     p_ptraverse myptraverse=bar(dot,(p_path)myli->data);
1335     inputs[i]=myptraverse->_admst;
1336     ptraverseinputs[i]=myptraverse;
1337     i++;
1338   }
1339   myadmst=new(mytransform,dot,inputs,size);
1340   xtraverse(mytransform->_children,myadmst,dot);
1341   deref(myadmst);
1342   for(i=0;i<size;i++)
1343     free_ptraverse(ptraverseinputs[i]);
1344   free(inputs);
1345 }
1346  /*[nepasimprimer]*/
Xpush(p_transform mytransform,p_admst dot,p_admst dotdot)1347 static void Xpush (p_transform mytransform,p_admst dot,p_admst dotdot)
1348 {
1349   p_slist myli;
1350   p_slist mylii;
1351   p_ptraverse pinto=bar(dot,mytransform->_pathinto);
1352   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1353   for(myli=pinto->_admst;myli;myli=myli->next)
1354   {
1355     p_admst myadmsti=(p_admst)myli->data;
1356     if(myadmsti->_pseudo==admse_basiclist)
1357     {
1358       p_slist mylistinto=((p_admstvariable)myadmsti->_item.p)->_value;
1359       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1360       {
1361         p_admst myadmstii=aread((p_admst)mylii->data);
1362         adms_slist_push(&mylistinto,(p_adms)myadmstii);
1363         if(myadmstii->_refd) myadmstii->_refd++;
1364       }
1365       ((p_admstvariable)myadmsti->_item.p)->_value=mylistinto;
1366     }
1367     else if(myadmsti->_pseudo==admse__ladmst)
1368     {
1369       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1370       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1371       {
1372         p_admst myadmstii=aread((p_admst)mylii->data);
1373         adms_slist_push(&mylistinto,(p_adms)myadmstii);
1374         if(myadmstii->_refd) myadmstii->_refd++;
1375       }
1376       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1377     }
1378     else if(myadmsti->_pseudo==admse__ladms)
1379     {
1380       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1381       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1382       {
1383         p_admst myadmstii=aread((p_admst)mylii->data);
1384         if(myadmstii->_pseudo==admse_basicstring)
1385           adms_slist_push(&mylistinto,(p_adms)adms_kclone(myadmstii->_item.s));
1386         else
1387           adms_slist_push(&mylistinto,myadmstii->_item.p);
1388       }
1389       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1390     }
1391   }
1392   free_ptraverse(pselect);
1393   free_ptraverse(pinto);
1394 }
1395 
Xpushonduplicate(p_transform mytransform,p_admst dot,p_admst dotdot)1396 static void Xpushonduplicate (p_transform mytransform,p_admst dot,p_admst dotdot)
1397 {
1398   p_slist myli;
1399   p_slist mylii;
1400   p_ptraverse pinto=bar(dot,mytransform->_pathinto);
1401   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1402   for(myli=pinto->_admst;myli;myli=myli->next)
1403   {
1404     p_admst myadmsti=(p_admst)myli->data;
1405     if(myadmsti->_pseudo==admse_basiclist)
1406     {
1407       p_slist mylistinto=((p_admstvariable)myadmsti->_item.p)->_value;
1408       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1409       {
1410         p_admst myadmstii=aread((p_admst)mylii->data);
1411         admse mytype0=myadmstii->_pseudo;
1412         int found=0;
1413         p_adms myadms0=myadmstii->_item.p;
1414         p_cmp mycmp=adms_admsxml_cmp(myadmstii);
1415         p_slist myliii;
1416         for(myliii=mylistinto;myliii&&!found;myliii=myliii->next)
1417         {
1418           p_admst myadmst1=(p_admst)myliii->data;
1419           p_adms myadms1=myadmst1->_item.p;
1420           admse mytype1=myadmst1->_pseudo;
1421           found=(mytype0==mytype1)&&(!mycmp(myadms0,myadms1));
1422         }
1423         if(!found)
1424         {
1425           adms_slist_push(&mylistinto,(p_adms)myadmstii);
1426           if(myadmstii->_refd) myadmstii->_refd++;
1427         }
1428       }
1429       ((p_admstvariable)myadmsti->_item.p)->_value=mylistinto;
1430     }
1431     else if(myadmsti->_pseudo==admse__ladmst)
1432     {
1433       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1434       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1435       {
1436         p_admst myadmstii=aread((p_admst)mylii->data);
1437         admse mytype0=myadmstii->_pseudo;
1438         int found=0;
1439         p_adms myadms0=myadmstii->_item.p;
1440         p_cmp mycmp=adms_admsxml_cmp(myadmstii);
1441         p_slist myliii;
1442         for(myliii=mylistinto;myliii&&!found;myliii=myliii->next)
1443         {
1444           p_admst myadmst1=(p_admst)myliii->data;
1445           p_adms myadms1=myadmst1->_item.p;
1446           admse mytype1=myadmst1->_pseudo;
1447           found=(mytype0==mytype1)&&(!mycmp(myadms0,myadms1));
1448         }
1449         if(!found)
1450         {
1451           adms_slist_push(&mylistinto,(p_adms)myadmstii);
1452           if(myadmstii->_refd) myadmstii->_refd++;
1453         }
1454       }
1455       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1456     }
1457     else if(myadmsti->_pseudo==admse__ladms)
1458     {
1459       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1460       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1461       {
1462         p_admst myadmstii=aread((p_admst)mylii->data);
1463         admse mytype0=myadmstii->_pseudo;
1464         int found=0;
1465         p_adms myadms0=myadmstii->_item.p;
1466         p_cmp mycmp=adms_admsxml_cmp(myadmstii);
1467         p_slist myliii;
1468         for(myliii=mylistinto;myliii&&!found;myliii=myliii->next)
1469         {
1470           p_adms myadms1=myliii->data;
1471           admse mytype1=myadms1?myadms1->_datatypename:admse_empty;
1472           found=(mytype0==mytype1)&&(!mycmp(myadms0,myadms1));
1473         }
1474         if(!found)
1475         {
1476           if(myadmstii->_pseudo==admse_basicstring)
1477             adms_slist_push(&mylistinto,(p_adms)adms_kclone(myadmstii->_item.s));
1478           else
1479             adms_slist_push(&mylistinto,myadmstii->_item.p);
1480         }
1481       }
1482       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1483     }
1484   }
1485   free_ptraverse(pselect);
1486   free_ptraverse(pinto);
1487 }
1488 
oncompare(p_ptraverse poncompareinto0,p_ptraverse poncompareinto1)1489 static int oncompare (p_ptraverse poncompareinto0, p_ptraverse poncompareinto1)
1490 {
1491   p_slist myl0=poncompareinto0->_admst;
1492   p_slist myl1=poncompareinto1->_admst;
1493   int allthesame=1;
1494   if(adms_slist_length(myl0)!=adms_slist_length(myl1))
1495     allthesame=0;
1496   else
1497   {
1498     for(;myl0&&allthesame;myl0=myl0->next,myl1=myl1->next)
1499     {
1500       p_admst myadmstcmp0=(p_admst)myl0->data;
1501       p_admst myadmstcmp1=(p_admst)myl1->data;
1502       allthesame=(myadmstcmp0->_item.p==myadmstcmp1->_item.p);
1503     }
1504   }
1505   free_ptraverse(poncompareinto1);
1506   return allthesame;
1507 }
oncompare1(p_ptraverse poncompareinto0,p_admst ai)1508 static int oncompare1 (p_ptraverse poncompareinto0, p_admst ai)
1509 {
1510   int found=0;
1511   p_slist lii=(p_slist)ai->_item.p;
1512   for(;lii&&!found;lii=lii->next)
1513   {
1514     p_admst d=adms_admst_newpa(ai,ai,lii->data);
1515     p_ptraverse poncompareinto1=bar(d,poncompareinto0->_transform->_pathoncompare);
1516     found=oncompare(poncompareinto0,poncompareinto1);
1517     adms_admst_free(d);
1518   }
1519   return found;
1520 }
Xpushoncompare(p_transform mytransform,p_admst dot,p_admst dotdot)1521 static void Xpushoncompare (p_transform mytransform,p_admst dot,p_admst dotdot)
1522 {
1523   p_slist myli;
1524   p_slist mylii;
1525   p_ptraverse pinto=bar(dot,mytransform->_pathinto);
1526   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1527   for(myli=pinto->_admst;myli;myli=myli->next)
1528   {
1529     p_admst myadmsti=(p_admst)myli->data;
1530     if(myadmsti->_pseudo==admse_basiclist)
1531     {
1532       p_slist mylistinto=((p_admstvariable)myadmsti->_item.p)->_value;
1533         for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1534         {
1535           p_admst myadmstii=aread((p_admst)mylii->data);
1536           p_ptraverse poncompareinto0=bar(myadmstii,mytransform->_pathoncompare);
1537           int found=0;
1538           p_slist myliii;
1539           for(myliii=mylistinto;myliii&&!found;myliii=myliii->next)
1540             found=oncompare(poncompareinto0,bar((p_admst)myliii->data,mytransform->_pathoncompare));
1541           if(!found)
1542           {
1543             adms_slist_push(&mylistinto,(p_adms)myadmstii);
1544             if(myadmstii->_refd) myadmstii->_refd++;
1545           }
1546           free_ptraverse(poncompareinto0);
1547         }
1548       ((p_admstvariable)myadmsti->_item.p)->_value=mylistinto;
1549     }
1550     else if(myadmsti->_pseudo==admse__ladmst)
1551     {
1552       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1553         for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1554         {
1555           p_admst myadmstii=aread((p_admst)mylii->data);
1556           p_ptraverse poncompareinto0=bar(myadmstii,mytransform->_pathoncompare);
1557           int found=0;
1558           p_slist myliii;
1559           for(myliii=mylistinto;myliii&&!found;myliii=myliii->next)
1560             found=oncompare(poncompareinto0,bar((p_admst)myliii->data,mytransform->_pathoncompare));
1561           if(!found)
1562           {
1563             adms_slist_push(&mylistinto,(p_adms)myadmstii);
1564             if(myadmstii->_refd) myadmstii->_refd++;
1565           }
1566           free_ptraverse(poncompareinto0);
1567         }
1568       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1569     }
1570     else if(myadmsti->_pseudo==admse__ladms)
1571     {
1572       p_slist mylistinto=(p_slist)myadmsti->_item.p;
1573       for(mylii=pselect->_admst;mylii;mylii=mylii->next)
1574       {
1575         p_admst myadmstii=aread((p_admst)mylii->data);
1576         p_ptraverse poncompareinto0=bar(myadmstii,mytransform->_pathoncompare);
1577         int found=0;
1578         found=oncompare1(poncompareinto0,myadmsti);
1579         if(!found)
1580         {
1581           if(myadmstii->_pseudo==admse_basicstring)
1582             adms_slist_push(&mylistinto,(p_adms)adms_kclone(myadmstii->_item.s));
1583           else
1584             adms_slist_push(&mylistinto,myadmstii->_item.p);
1585         }
1586         free_ptraverse(poncompareinto0);
1587       }
1588       ((p_valueto)myadmsti->_valueto)(myadmsti->_previous->_item.p,(p_adms)mylistinto);
1589     }
1590   }
1591   free_ptraverse(pselect);
1592   free_ptraverse(pinto);
1593 }
1594  /*[nepasimprimer]*/
Xreset(p_transform mytransform,p_admst dot,p_admst dotdot)1595 static void Xreset (p_transform mytransform,p_admst dot,p_admst dotdot)
1596 {
1597   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1598   p_slist myli=pselect->_admst;
1599   for(;myli;myli=myli->next)
1600   {
1601     p_admst myadmst=(p_admst)myli->data;
1602     if(myadmst->_pseudo==admse_basiclist)
1603       ((p_admstvariable)myadmst->_item.p)->_value=NULL;
1604     else if(myadmst->_pseudo==admse__ladms || myadmst->_pseudo==admse__ladmst)
1605       awrite(mytransform,(p_admst)myli->data,NULL);
1606   }
1607   free_ptraverse(pselect);
1608 }
1609  /*[nepasimprimer]*/
Xreverse(p_transform mytransform,p_admst dot,p_admst dotdot)1610 static void Xreverse (p_transform mytransform,p_admst dot,p_admst dotdot)
1611 {
1612   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1613   p_slist myli=pselect->_admst;
1614   for(;myli;myli=myli->next)
1615   {
1616     p_admst myadmst=(p_admst)myli->data;
1617     if(myadmst->_pseudo==admse_basiclist)
1618       adms_slist_inreverse(&((p_admstvariable)myadmst->_item.p)->_value);
1619     else if(myadmst->_pseudo==admse__ladms || myadmst->_pseudo==admse__ladmst)
1620     {
1621       p_slist mylist=(p_slist)myadmst->_item.p;
1622       adms_slist_inreverse(&mylist);
1623       ((p_valueto)myadmst->_valueto)(myadmst->_previous->_item.p,(p_adms)mylist);
1624     }
1625   }
1626   free_ptraverse(pselect);
1627 }
1628  /*[nepasimprimer]*/
Xread(p_transform mytransform,p_admst dot,p_admst dotdot)1629 static void Xread (p_transform mytransform,p_admst dot,p_admst dotdot)
1630 {
1631   char* myfilename=tsprintf(dot,mytransform->_textfile);
1632   parseva(1,NULL,myfilename);
1633 }
1634  /*[nepasimprimer]*/
Xopen(p_transform mytransform,p_admst dot,p_admst dotdot)1635 static void Xopen (p_transform mytransform,p_admst dot,p_admst dotdot)
1636 {
1637   char* myfilename=tsprintf(dot,mytransform->_textfile);
1638   FILE*ofh;
1639   if(!(ofh=fopen(myfilename,"wb")))
1640     adms_message_fatal(("%s: failed to open file [write mode]\n",myfilename))
1641   if(ofh)
1642     adms_slist_push(&globalfileoutputlist,(p_adms)ofh);
1643   else
1644    adms_message_fatal(("%s: cannot open file.\n",adms_transform_uid(mytransform)))
1645   xtraverse(mytransform->_children,dot,dotdot);
1646   fclose(OUT());
1647   adms_slist_pull(&globalfileoutputlist);
1648   free(myfilename);
1649 }
1650  /*[nepasimprimer]*/
Xsetenv(p_transform mytransform,p_admst dot,p_admst dotdot)1651 static void Xsetenv (p_transform mytransform,p_admst dot,p_admst dotdot)
1652 {
1653   char* myname=tsprintf(dot,mytransform->_textname);
1654   char* mystring=tsprintf(dot,mytransform->_textstring);
1655   if(!adms_setenv(myname,mystring))
1656   {
1657     adms_message_fatal(("cannot set shell variable: '%s=%s'\n",myname,mystring))
1658     adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
1659   }
1660   free(myname);
1661   free(mystring);
1662 }
1663  /*[nepasimprimer]*/
Xcount(p_transform mytransform,p_admst dot,p_admst dotdot)1664 static void Xcount (p_transform mytransform,p_admst dot,p_admst dotdot)
1665 {
1666   p_ptraverse pselect=bar(dot,mytransform->_pathselect);
1667   adms_push_admst(adms_admst_newbi(dot,dot,adms_slist_length(pselect->_admst)),mytransform);
1668   free_ptraverse(pselect);
1669 }
1670  /*[nepasimprimer]*/
Xgetenv(p_transform mytransform,p_admst dot,p_admst dotdot)1671 static void Xgetenv (p_transform mytransform,p_admst dot,p_admst dotdot)
1672 {
1673   char* myname=tsprintf(dot,mytransform->_textname);
1674   const char* myenv=getenv(myname);
1675   if(myenv==NULL)
1676   {
1677     adms_message_fatal_continue(("missing shell variable '%s'\n",myname))
1678     adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
1679   }
1680   adms_push_admst(adms_admst_newns(dot,dot,adms_kclone(myenv)),mytransform);
1681   free(myname);
1682 }
1683  /*[nepasimprimer]*/
Xcopy(p_transform mytransform,p_admst dot,p_admst dotdot)1684 static void Xcopy (p_transform mytransform,p_admst dot,p_admst dotdot)
1685 {
1686   FILE*fromfh;
1687   FILE*tofh;
1688   char buf[1024];
1689   char* tfrom=tsprintf(dot,mytransform->_textfrom);
1690   char* tto=tsprintf(dot,mytransform->_textto);
1691   char* myfromfile=filename(tfrom);
1692   char* myfrombasename=basename(myfromfile);
1693   char* myfromdirname=dirname(myfromfile);
1694   char* mytopath=filename(tto);
1695   char* mytofilename=NULL;
1696   char* mytodirname=NULL;
1697   free(tfrom);
1698   free(tto);
1699   if(!adms_file_isregular(myfromfile))
1700     adms_message_fatal(("%s: from=`%s' file not found\n",adms_transform_uid(mytransform),myfromfile))
1701   if(adms_file_isdirectory(mytopath))
1702   {
1703     adms_k2strconcat(&mytodirname,mytopath);
1704     adms_k2strconcat(&mytofilename,mytopath);
1705     adms_k2strconcat(&mytofilename,ADMS_PATH_SEPARATOR);
1706     adms_k2strconcat(&mytofilename,myfrombasename);
1707   }
1708   else
1709   {
1710     mytodirname=dirname(mytopath);
1711     if(adms_file_isdirectory(mytodirname))
1712       adms_k2strconcat(&mytofilename,mytopath);
1713     else
1714       adms_message_fatal(("%s: to=`%s' invalid directory\n",adms_transform_uid(mytransform),mytodirname))
1715   }
1716   if(!strcmp(myfromdirname,mytodirname))
1717     adms_message_fatal(("%s: file '%s' copied to itself!\n",adms_transform_uid(mytransform),myfromfile))
1718   fromfh=fopen(myfromfile,"rb");
1719   tofh=fopen(mytofilename,"wb");
1720   if(!fromfh)
1721     adms_message_fatal(("%s: from=`%s' cannot open file [read mode]\n",adms_transform_uid(mytransform),myfromfile))
1722   if(!tofh)
1723     adms_message_fatal(("%s: to=`%s' cannot open file [write mode]\n",adms_transform_uid(mytransform),mytopath))
1724   while(!feof(fromfh))
1725   {
1726     size_t newbytes=fread(buf,sizeof(char),sizeof(buf),fromfh);
1727     if(ferror(fromfh))
1728       adms_message_fatal(("%s: from=`%s' cannot read file contents\n",adms_transform_uid(mytransform),myfromfile))
1729     fwrite(buf,sizeof(char),newbytes,tofh);
1730   }
1731   fclose(tofh);
1732   fclose(fromfh);
1733   adms_message_verbose(("%s: copy file '%s' to '%s'\n",adms_transform_uid(mytransform),myfromfile,mytofilename))
1734   free(myfromfile);
1735   free(myfromdirname);
1736   free(myfrombasename);
1737   free(mytopath);
1738   free(mytodirname);
1739   free(mytofilename);
1740 }
1741  /*[nepasimprimer]*/
1742 struct sa {char *e1; char *nom; char *e2; /*=*/ char *e3; char *valeur; struct sa *X;};
1743 struct sb {char *nom; char* e; struct sa *a0; struct sa *a;};
texttoxml(const char * s)1744 static void texttoxml (const char*s)
1745 {
1746   adms_message_admstdbg_impl("%s",s);
1747 }
xmltotxt(char * s)1748 static char* xmltotxt (char*s)
1749 {
1750   char*s0=s;
1751   char*s1=s;
1752   while(*s)
1753   {
1754     if(!strncmp(s,"\r\n",2))
1755       *s1='\n',s+=2;
1756     else if(!strncmp(s,"&quot;",6))
1757       *s1='\"',s+=6;
1758     else if(!strncmp(s,"&amp;",5))
1759       *s1='&',s+=5;
1760     else if(!strncmp(s,"&lt;",4))
1761       *s1='<',s+=4;
1762     else if(!strncmp(s,"&gt;",4))
1763       *s1='>',s+=4;
1764     else if(!strncmp(s,"&apos;",6))
1765       *s1='\'',s+=6;
1766     else
1767       *s1=*s,s++;
1768     s1++;
1769   }
1770   *s1='\0';
1771   s0=realloc(s0,(s1-s0+1)*sizeof(char));
1772   return s0;
1773 }
xmlstrncpy(char * d,const char * o,int n)1774 static int xmlstrncpy (char*d,const char*o,int n)
1775 {
1776   int l=0;
1777   char*d0=d;
1778   while(*o&&n)
1779   {
1780     if(!strncmp(o,"\r\n",2))
1781       l++,*d='\n',o+=2,n-=2;
1782     else if(!strncmp(o,"\n",1))
1783       l++,*d='\n',o+=1,n-=1;
1784     else
1785       *d=*o,o++,n--;
1786     d++;
1787   }
1788   *d='\0';
1789   d0=realloc(d0,(d-d0+1)*sizeof(char));
1790   return l;
1791 }
xmlmemcpy(char * d,const char * o,int n,int * nl)1792 static char* xmlmemcpy (char*d,const char*o,int n,int *nl)
1793 {
1794   char*d0=d;
1795   while(*o&&n)
1796   {
1797     if(!strncmp(o,"\r\n",2))
1798       *nl=*nl+1,*d=*o,d++,o++,n--;
1799     else if(!strncmp(o,"\n",1))
1800       *nl=*nl+1;
1801     *d=*o,d++,o++,n--;
1802   }
1803   *d='\0';
1804   return d0;
1805 }
xmlisspace(const char c,int * L)1806 static int xmlisspace (const char c,int* L)
1807 {
1808   if(c=='\n')
1809     {*L+=1;return 1;}
1810   else
1811     return isspace(c);
1812 }
1813  /*[nepasimprimer]*/
1814 #define FRfr_XMLFATAL0 "ben alors! ne commence pas par un nom\n"
1815 #define FRfr_XMLFATAL1 "ben alors! et le nom d'attribut devant le signe =.\n"
1816 #define FRfr_XMLFATAL2 "ben alors! le charactere = ?\n"
1817 #define FRfr_XMLFATAL3 "ben alors! le charactere \" ?\n"
1818 #define FRfr_XMLFATAL4 "ben alors! la valeur n'est pas terminee par le charactere \" ?\n"
1819 #define ANcn_XMLFATAL0 "%s:%i: tag doesn't start with a name\n",monfichier,*L
1820 #define ANcn_XMLFATAL1 "%s:%i: attribute name expected before character =\n",monfichier,*L
1821 #define ANcn_XMLFATAL2 "%s:%i: inside tag character \'=\' expected\n",monfichier,*L
1822 #define ANcn_XMLFATAL3 "%s:%i: inside tag character \'\"\' expected\n",monfichier,*L
1823 #define ANcn_XMLFATAL4 "%s:%i: unterminated attribute value - character \" expected\n",monfichier,*L
1824 #define XMLFATAL0 ANcn_XMLFATAL0
1825 #define XMLFATAL1 ANcn_XMLFATAL1
1826 #define XMLFATAL2 ANcn_XMLFATAL2
1827 #define XMLFATAL3 ANcn_XMLFATAL3
1828 #define XMLFATAL4 ANcn_XMLFATAL4
balisenouveau(const char ** cp,int * L,const char * monfichier)1829 struct sb* balisenouveau(const char **cp,int* L,const char *monfichier)
1830 {
1831   struct sb* balisep=malloc(sizeof(struct sb));
1832   struct sb balise;
1833   const char*c=*cp;
1834   const char*c0=c;
1835   balise.nom=NULL;
1836   balise.e=NULL;
1837   balise.a0=NULL;
1838   balise.a=NULL;
1839   for(;*c&&!isspace(*c)&&strncmp(c,">",1)&&strncmp(c,"/>",2);c++);
1840   if(c-c0)
1841     balise.nom=malloc(sizeof(char)*(c-c0+1)),
1842     balise.e=NULL,
1843     balise.a0=NULL,
1844     memcpy(balise.nom,c0,c-c0),balise.nom[c-c0]='\0';
1845   else
1846     adms_message_fatal((XMLFATAL0))
1847   while(*c)
1848   {
1849     char*e1;
1850     c0=c;for(;*c&&xmlisspace(*c,L);c++);
1851     if(!strncmp(c,">",1)||!strncmp(c,"/>",2)||!*c)
1852     {
1853       balise.e=malloc(sizeof(char)*(c-c0+1)),
1854       strncpy(balise.e,c0,c-c0),
1855       balise.e[c-c0]='\0';
1856       break;
1857     }
1858     e1=malloc(sizeof(char)*(c-c0+1));
1859     strncpy(e1,c0,c-c0);
1860     e1[c-c0]='\0';
1861     c0=c;for(;*c&&!isspace(*c)&&(*c!='=');c++);
1862     if(c==c0)
1863       adms_message_fatal((XMLFATAL1))
1864     if(balise.a0)
1865       balise.a=balise.a->X=malloc(sizeof(struct sa)),
1866       balise.a->X=NULL;
1867     else
1868       balise.a=balise.a0=malloc(sizeof(struct sa)),
1869       balise.a->X=NULL;
1870     balise.a->nom=malloc(sizeof(char)*(c-c0+1));
1871     balise.a->e1=e1;
1872     memcpy(balise.a->nom,c0,c-c0),balise.a->nom[c-c0]='\0';
1873     c0=c;for(;*c&&xmlisspace(*c,L);c++);
1874     balise.a->e2=malloc(sizeof(char)*(c-c0+1)),
1875     strncpy(balise.a->e2,c0,c-c0),
1876     balise.a->e2[c-c0]='\0';
1877     if(*c!='=')
1878       adms_message_fatal((XMLFATAL2))
1879     c++;
1880     c0=c;for(;*c&&xmlisspace(*c,L);c++);
1881     balise.a->e3=malloc(sizeof(char)*(c-c0+1)),
1882     strncpy(balise.a->e3,c0,c-c0),
1883     balise.a->e3[c-c0]='\0';
1884     if(*c!='"')
1885       adms_message_fatal((XMLFATAL3))
1886     c++;
1887     c0=c;for(;*c&&(*c!='\"');c++);
1888     if(*c!='\"')
1889       adms_message_fatal((XMLFATAL4))
1890     balise.a->valeur=malloc(sizeof(char)*(c-c0+1));
1891     balise.a->valeur=xmlmemcpy(balise.a->valeur,c0,c-c0,L);
1892     c++;
1893   }
1894   *balisep=balise;
1895   *cp=c;
1896   return balisep;
1897 }
1898 typedef struct sx* px;
1899 struct sx { int l; int c; const char* f; char *contenu; struct sb* bp;
1900   px r; px x; px X; px y; px Y0; px Y;
1901   void (*adms) (const px xp);
1902   void (*dbg) (const px xp);
1903 };
1904 px noeud_courant=NULL;
racinedbg(const px xp)1905 static void racinedbg (const px xp)
1906 {
1907   px Y;
1908   for(Y=xp->Y0;Y;Y=Y->X)
1909     (Y->dbg)(Y);
1910 }
instructiondbg(const px xp)1911 static void instructiondbg (const px xp)
1912 {
1913   adms_message_admstdbg_impl("<!--%s:%i--> <?",xp->f,xp->l);
1914   texttoxml(xp->contenu);
1915   adms_message_admstdbg_impl("?>");
1916 }
declarationdbg(const px xp)1917 static void declarationdbg (const px xp)
1918 {
1919   adms_message_admstdbg_impl("<!--%s:%i--> <?was_xml ",xp->f,xp->l);
1920   texttoxml(xp->contenu);
1921   adms_message_admstdbg_impl("?>");
1922 }
typededocumentdbg(const px xp)1923 static void typededocumentdbg (const px xp)
1924 {
1925   adms_message_admstdbg_impl("<!--%s:%i--> <?was_DOCTYPE !DOCTYPE",xp->f,xp->l);
1926   texttoxml(xp->contenu);
1927   adms_message_admstdbg_impl("?>");
1928 }
commentairedbg(const px xp)1929 static void commentairedbg (const px xp)
1930 {
1931   adms_message_admstdbg_impl("<!--%s:%i--> <!--",xp->f,xp->l);
1932   texttoxml(xp->contenu);
1933   adms_message_admstdbg_impl("-->");
1934 }
debutbalisedbg(const px xp)1935 static void debutbalisedbg (const px xp)
1936 {
1937   if(!strcmp(xp->bp->nom,"admst"))
1938     adms_message_admstdbg_impl("<!--%s:%i--> <?was_admst_begin ?>",xp->f,xp->l);
1939   else
1940   {
1941     adms_message_admstdbg_impl("<!--%s:%i--> <%s",xp->f,xp->l,xp->bp->nom);
1942     for(xp->bp->a=xp->bp->a0;xp->bp->a;xp->bp->a=xp->bp->a->X)
1943       adms_message_admstdbg_impl("%s",xp->bp->a->e1),
1944       adms_message_admstdbg_impl("%s",xp->bp->a->nom),
1945       adms_message_admstdbg_impl("%s",xp->bp->a->e2),
1946       adms_message_admstdbg_impl("="),
1947       adms_message_admstdbg_impl("%s",xp->bp->a->e3),
1948       adms_message_admstdbg_impl("\""),
1949       texttoxml(xp->bp->a->valeur),
1950       adms_message_admstdbg_impl("\"");
1951     adms_message_admstdbg_impl("%s",xp->bp->e);
1952     adms_message_admstdbg_impl(">");
1953   }
1954   for(xp->Y=xp->Y0;xp->Y;xp->Y=xp->Y->X)
1955     (xp->Y->dbg)(xp->Y);
1956 }
balisefeuilledbg(const px xp)1957 static void balisefeuilledbg (const px xp)
1958 {
1959   adms_message_admstdbg_impl("<!--%s:%i--> <%s",xp->f,xp->l,xp->bp->nom);
1960   for(xp->bp->a=xp->bp->a0;xp->bp->a;xp->bp->a=xp->bp->a->X)
1961     adms_message_admstdbg_impl("%s",xp->bp->a->e1),
1962     adms_message_admstdbg_impl("%s",xp->bp->a->nom),
1963     adms_message_admstdbg_impl("%s",xp->bp->a->e2),
1964     adms_message_admstdbg_impl("="),
1965     adms_message_admstdbg_impl("%s",xp->bp->a->e3),
1966     adms_message_admstdbg_impl("\""),
1967     texttoxml(xp->bp->a->valeur),
1968     adms_message_admstdbg_impl("\"");
1969   adms_message_admstdbg_impl("%s",xp->bp->e);
1970   adms_message_admstdbg_impl("/>");
1971 }
findebalisedbg(const px xp)1972 static void findebalisedbg (const px xp)
1973 {
1974   if(!strcmp(xp->bp->nom,"admst"))
1975     adms_message_admstdbg_impl("<!--%s:%i--> <?was_admst_end ?>",xp->f,xp->l);
1976   else
1977   {
1978     adms_message_admstdbg_impl("<!--%s:%i--> </",xp->f,xp->l);
1979     adms_message_admstdbg_impl("%s",xp->bp->nom);
1980     adms_message_admstdbg_impl("%s",xp->bp->e);
1981     adms_message_admstdbg_impl(">");
1982   }
1983 }
textedbg(const px xp)1984 static void textedbg (const px xp)
1985 {
1986   texttoxml(xp->contenu);
1987 }
1988 
1989 static void xmlhook_start (const px xp);
1990 static void xmlhook_end (const px xp);
1991 static void xmlhook_text (const px xp);
1992 
racineadms(const px xp)1993 static void racineadms (const px xp)
1994 {
1995   px Y;
1996   for(Y=xp->Y0;Y;Y=Y->X)
1997     (Y->adms)(Y);
1998 }
instructionadms(const px xp)1999 static void instructionadms (const px xp) {}
declarationadms(const px xp)2000 static void declarationadms (const px xp) {}
typededocumentadms(const px xp)2001 static void typededocumentadms (const px xp) {}
commentaireadms(const px xp)2002 static void commentaireadms (const px xp) {}
debutbaliseadms(const px xp)2003 static void debutbaliseadms (const px xp)
2004 {
2005   xmlhook_start(xp);
2006   for(xp->Y=xp->Y0;xp->Y;xp->Y=xp->Y->X)
2007     (xp->Y->adms)(xp->Y);
2008 }
balisefeuilleadms(const px xp)2009 static void balisefeuilleadms (const px xp)
2010 {
2011   xmlhook_start(xp);
2012   xmlhook_end(xp);
2013 }
findebaliseadms(const px xp)2014 static void findebaliseadms (const px xp)
2015 {
2016   xmlhook_end(xp);
2017 }
texteadms(const px xp)2018 static void texteadms (const px xp)
2019 {
2020   xmlhook_text(xp);
2021 }
2022 struct sx racine={0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,racineadms,racinedbg};
2023 #define noeuds n(instruction) n(declaration) n(typededocument) n(commentaire) n(debutbalise) n(balisefeuille) n(findebalise) n(texte)
2024 #undef n
2025 #define n(I) static px I##new (char* contenu,struct sb* bp,const char*monfichier,const px y,const int l,const int c) \
2026 {\
2027   px xp=malloc(sizeof(struct sx)); \
2028   xp->l=l; \
2029   xp->c=c; \
2030   xp->f=monfichier; \
2031   xp->y=y; \
2032   xp->Y0=NULL; \
2033   xp->Y=NULL; \
2034   xp->x=NULL; \
2035   xp->X=NULL; \
2036   xp->contenu=contenu; \
2037   xp->bp=bp; \
2038   xp->dbg= I## dbg; \
2039   xp->adms= I## adms; \
2040   if(y->Y0==NULL) y->Y=y->Y0=xp; \
2041   else {y->Y=y->Y->X=xp;} \
2042   return xp; \
2043 }
2044 noeuds
2045 #undef n
2046  /*[nepasimprimer]*/
arbre(const char * s,const char * monfichier)2047 static void arbre (const char *s,const char*monfichier)
2048 {
2049   int L=1;
2050   noeud_courant=&racine;
2051   for(;*s;s++)
2052   {
2053     if(0) {}
2054     else if(!strncmp(s,"<?admst-skip-implicit?>",23))
2055     {
2056       const char*s0=s;
2057       int l;
2058       char*contenu;
2059       s+=23;
2060       l=s-s0;
2061       contenu=malloc(sizeof(char)*(l+1));
2062       declarationnew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2063       L+=xmlstrncpy(contenu,s0,l);
2064     }
2065     else if(!strncmp(s,"<?xml",5))
2066     {
2067       const char*s0;
2068       s+=5;
2069       for(s0=s;*s&&!((s>s0+0)&&!strncmp(s-1,"?>",2));s++);
2070       if(*s)
2071       {
2072         int l=s-s0-1;
2073         char*contenu=malloc(sizeof(char)*(l+1));
2074         declarationnew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2075         L+=xmlstrncpy(contenu,s0,l);
2076       }
2077       else
2078         adms_message_fatal(("%s:%i: xml declaration unterminated '%.20s'\n",monfichier,L,s0))
2079     }
2080     else if(!strncmp(s,"<?",2))
2081     {
2082       const char*s0;
2083       s+=2;
2084       for(s0=s;*s&&!((s>s0+0)&&!strncmp(s-1,"?>",2));s++);
2085       if(*s)
2086       {
2087         int l=s-s0-1;
2088         char*contenu=malloc(sizeof(char)*(l+1));
2089         instructionnew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2090         L+=xmlstrncpy(contenu,s0,l);
2091       }
2092       else
2093         adms_message_fatal(("%s:%i: xml instruction declaration unterminated '%.20s'\n",monfichier,L,s0))
2094     }
2095     else if(!strncmp(s,"<!--",4))
2096     {
2097       const char*s0;
2098       s+=4;
2099       for(s0=s;*s&&!((s>s0+1)&&!strncmp(s-2,"-->",3));s++);
2100       if(*s)
2101       {
2102         int l=s-s0-2;
2103         char*contenu=malloc(sizeof(char)*(l+1));
2104         commentairenew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2105         L+=xmlstrncpy(contenu,s0,l);
2106       }
2107       else
2108         adms_message_fatal(("%s:%i: xml comment declaration unterminated '%.20s'\n",monfichier,L,s0))
2109     }
2110     else if(!strncmp(s,"<!DOCTYPE",9))
2111     {
2112       const char*s0;
2113       s+=9;
2114       for(s0=s;*s&&*s!='>';s++);
2115       if(*s)
2116       {
2117         int l=s-s0-0;
2118         char*contenu=malloc(sizeof(char)*(l+1));
2119         typededocumentnew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2120         L+=xmlstrncpy(contenu,s0,l);
2121       }
2122       else
2123         adms_message_fatal(("%s:%i: xml doctype declaration unterminated '%.20s'\n",monfichier,L,s0))
2124     }
2125     else if(!strncmp(s,"</",2))
2126     {
2127       struct sb* balisep=malloc(sizeof(struct sb));
2128       int L0=L;
2129       const char*s0;
2130       s+=2;
2131       for(s0=s;*s&&!isspace(*s)&&*s!='>';s++);
2132       if(s-s0)
2133         balisep->nom=malloc(sizeof(char)*(s-s0+1)),
2134         balisep->e=NULL,
2135         balisep->a0=NULL,
2136         memcpy(balisep->nom,s0,s-s0),balisep->nom[s-s0]='\0';
2137       else
2138         adms_message_fatal(("%s:%i: end tag unterminated '%.20s'\n",monfichier,L0,s0))
2139       s0=s;for(;*s&&xmlisspace(*s,&L);s++);
2140       balisep->e=malloc(sizeof(char)*(s-s0+1)),
2141       strncpy(balisep->e,s0,s-s0),
2142       balisep->e[s-s0]='\0';
2143       if(*s&&*s=='>')
2144       {
2145         findebalisenew(NULL,balisep,monfichier,noeud_courant,L0,s-s0);
2146         if(!noeud_courant->bp)
2147           adms_message_fatal(("%s:%i: end tag '%s' floating\n",monfichier,L0,balisep->nom))
2148         if(strcmp(noeud_courant->bp->nom,balisep->nom))
2149         {
2150           adms_message_fatal_continue(("%s:%i: end tag mismatch '%s'\n",monfichier,L0,balisep->nom))
2151           adms_message_fatal(("%s:%i: current open tag '%s'\n",monfichier,noeud_courant->l,noeud_courant->bp->nom))
2152         }
2153         noeud_courant=(noeud_courant&&(noeud_courant!=&racine))?noeud_courant->y:NULL;
2154       }
2155       else
2156         adms_message_fatal(("%s:%i: end tag unterminated '%.20s'\n",monfichier,L0,s0))
2157     }
2158     else if(*s=='<')
2159     {
2160       int L0=L;
2161       const char*s0=++s;
2162       struct sb* bp=balisenouveau(&s,&L,monfichier);
2163       if(!strncmp(s,"/>",2))
2164         s++,
2165         balisefeuillenew(NULL,bp,monfichier,noeud_courant,L0,s-s0);
2166       else if(!strncmp(s,">",1))
2167         noeud_courant=debutbalisenew(NULL,bp,monfichier,noeud_courant,L0,s-s0);
2168       else
2169         adms_message_fatal(("%s:%i: tag badly formed '%.20s'\n",monfichier,L0,s0))
2170     }
2171     else
2172     {
2173       const char*s0;
2174       for(s0=s;*s&&*s!='<';s++);
2175       if(s>s0)
2176       {
2177         char*contenu=malloc(sizeof(char)*(s-s0+1));
2178         textenew(contenu,NULL,monfichier,noeud_courant,L,s-s0);
2179         noeud_courant->Y->contenu=xmlmemcpy(contenu,s0,s-s0,&L);
2180         s--;
2181       }
2182     }
2183   }
2184 }
2185  /*[nepasimprimer]*/
2186 #undef T
2187 #define T(p) !strcmp(mytransform->_name,#p)
setcallback(p_transform mytransform)2188 static void setcallback (p_transform mytransform)
2189 {
2190   if(T(admst:if-inside))
2191   {
2192     if(mytransform->_textlist->_admse==admse__p) mytransform->_callback=(void*)Xifinsidep,mytransform->_id="Xifinsidep";
2193     else if(mytransform->_textlist->_admse==admse__path) mytransform->_callback=(void*)Xifinsidepath,mytransform->_id="Xifinsidepath";
2194     else
2195     {
2196       adms_message_fatal_continue(("'list' should be exactly '%%p' or '%%(...)'\n"))
2197       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
2198     }
2199   }
2200   else if(T(admst:if-not-inside))
2201   {
2202     if(mytransform->_textlist->_admse==admse__p) mytransform->_callback=(void*)Xifnotinsidep,mytransform->_id="Xifnotinsidep";
2203     else if(mytransform->_textlist->_admse==admse__path) mytransform->_callback=(void*)Xifnotinsidepath,mytransform->_id="Xifnotinsidepath";
2204     else
2205     {
2206       adms_message_fatal_continue(("'list' should be exactly '%%p' or '%%(...)'\n"))
2207       adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
2208     }
2209   }
2210   else if(T(admst:variable))
2211   {
2212 
2213     if(mytransform->_textselect)
2214     {
2215       if(mytransform->_textselect->_admse==admse__p)
2216         mytransform->_callback=(void*)Xvariablep,
2217         mytransform->_id="Xvariablep";
2218       else if(mytransform->_textselect->_admse==admse__path)
2219         mytransform->_callback=(void*)Xvariable,
2220         mytransform->_id="Xvariable",
2221         mytransform->_pathpath=(p_path)mytransform->_textselect->_token->data;
2222       else if((adms_slist_length(mytransform->_textselect->_token)==1)&&(mytransform->_textselect->_token->data->_datatypename==admse_admst))
2223         mytransform->_callback=(void*)Xvariableconstant,
2224         mytransform->_id="Xvariableconstant",
2225         mytransform->_textstring=mytransform->_textselect;
2226       else
2227         mytransform->_callback=(void*)Xvariablestring,
2228         mytransform->_id="Xvariablestring",
2229         mytransform->_textstring=mytransform->_textselect;
2230     }
2231     else if(mytransform->_textstring)
2232     {
2233       if((adms_slist_length(mytransform->_textstring->_token)==1)&&(mytransform->_textstring->_token->data->_datatypename==admse_admst))
2234         mytransform->_callback=(void*)Xvariableconstant,
2235         mytransform->_id="Xvariableconstant";
2236       else
2237         mytransform->_callback=(void*)Xvariablestring,
2238         mytransform->_id="Xvariablestring";
2239     }
2240     else if(mytransform->_pathpath)
2241       mytransform->_callback=(void*)Xvariable,
2242       mytransform->_id="Xvariable";
2243     else
2244       mytransform->_callback=(void*)Xvariablenull,
2245       mytransform->_id="Xvariablenull";
2246   }
2247   else if(T(admst:value-to))
2248   {
2249     if(mytransform->_textstring)
2250     {
2251       if(mytransform->_textstring->_admse==admse__p)
2252         mytransform->_callback=(void*)Xvaluetop,
2253         mytransform->_id="Xvaluetop";
2254       else if(mytransform->_textstring->_admse==admse__path)
2255         mytransform->_callback=(void*)Xvaluetopath,
2256         mytransform->_id="Xvaluetopath";
2257       else if((adms_slist_length(mytransform->_textstring->_token)==1)&&(mytransform->_textstring->_token->data->_datatypename==admse_admst))
2258         mytransform->_callback=(void*)Xvaluetoconstant,
2259         mytransform->_id="Xvaluetoconstant";
2260       else
2261         mytransform->_callback=(void*)Xvaluetostring,
2262         mytransform->_id="Xvaluetostring";
2263     }
2264     else if(mytransform->_pathpath)
2265       mytransform->_callback=(void*)Xvalueto,
2266       mytransform->_id="Xvalueto";
2267     else
2268       mytransform->_callback=(void*)Xvaluetonull,
2269       mytransform->_id="Xvaluetonull";
2270   }
2271   else if(T(admst:text)) mytransform->_callback=(void*)Xtext,mytransform->_id="Xtext";
2272   else if(T(admst:new)&&((mytransform->_textarguments))) mytransform->_callback=(void*)Xnewarguments,mytransform->_id="Xnewarguments";
2273   else if(T(admst:new)&&((mytransform->_pathinputs))) mytransform->_callback=(void*)Xnew,mytransform->_id="Xnew";
2274   else if(T(admst)) mytransform->_callback=(void*)Xadmst,mytransform->_id="Xadmst";
2275   else if(T(admst:for-each)) mytransform->_callback=(void*)Xforeach,mytransform->_id="Xforeach";
2276   else if(T(admst:join)) mytransform->_callback=(void*)Xjoin,mytransform->_id="Xjoin";
2277   else if(T(admst:break)) mytransform->_callback=(void*)Xbreak,mytransform->_id="Xbreak";
2278   else if(T(admst:value-of)) mytransform->_callback=(void*)Xvalueof,mytransform->_id="Xvalueof";
2279   else if(T(admst:choice)||T(admst:choose)) mytransform->_callback=(void*)Xchoose,mytransform->_id="Xchoose";
2280   else if(T(admst:when)) {mytransform->_id="Xnull_when";}
2281   else if(T(admst:otherwise)) {mytransform->_id="Xnull_otherwise";}
2282   else if(T(admst:if)) mytransform->_callback=(void*)Xif,mytransform->_id="Xif";
2283   else if(T(admst:templates)||T(admst:template)) {mytransform->_id="Xnull_template";}
2284   else if(T(admst:apply-template)||T(admst:apply-templates)) mytransform->_callback=(void*)Xapplytemplates,mytransform->_id="Xapplytemplates";
2285   else if(T(admst:return)) mytransform->_callback=(void*)Xreturn,mytransform->_id="Xreturn";
2286   else if(T(admst:attribute)) mytransform->_callback=(void*)Xattribute,mytransform->_id="Xattribute";
2287   else if(T(admst:push))
2288   {
2289     if(mytransform->_pathoncompare)
2290       mytransform->_callback=(void*)Xpushoncompare,mytransform->_id="Xpushoncompare";
2291     else if(mytransform->_textonduplicate&&!strcmp(tsprintf(NULL,mytransform->_textonduplicate),"ignore"))
2292       mytransform->_callback=(void*)Xpushonduplicate,mytransform->_id="Xpushonduplicate";
2293     else
2294       mytransform->_callback=(void*)Xpush,mytransform->_id="Xpush";
2295   }
2296   else if(T(admst:reset)) mytransform->_callback=(void*)Xreset,mytransform->_id="Xreset";
2297   else if(T(admst:count)) mytransform->_callback=(void*)Xcount,mytransform->_id="Xcount";
2298   else if(T(admst:reverse)) mytransform->_callback=(void*)Xreverse,mytransform->_id="Xreverse";
2299   else if(T(admst:read)) mytransform->_callback=(void*)Xread,mytransform->_id="Xread";
2300   else if(T(admst:open)) mytransform->_callback=(void*)Xopen,mytransform->_id="Xopen";
2301   else if(T(admst:setenv)) mytransform->_callback=(void*)Xsetenv,mytransform->_id="Xsetenv";
2302   else if(T(admst:getenv)) mytransform->_callback=(void*)Xgetenv,mytransform->_id="Xgetenv";
2303   else if(T(admst:copy)) mytransform->_callback=(void*)Xcopy,mytransform->_id="Xcopy";
2304   else if(T(admst:assert)) mytransform->_callback=(void*)Xassert,mytransform->_id="Xassert";
2305   else if(T(admst:message)) mytransform->_callback=(void*)Xmessage,mytransform->_id="Xmessage";
2306   else if(T(admst:warning)) mytransform->_callback=(void*)Xwarning,mytransform->_id="Xwarning";
2307   else if(T(admst:error)) mytransform->_callback=(void*)Xerror,mytransform->_id="Xerror";
2308   else if(T(admst:fatal)) mytransform->_callback=(void*)Xfatal,mytransform->_id="Xfatal";
2309   else adms_message_fatal(("%s: unknown transform\n",adms_transform_uid(mytransform)))
2310 }
setkeeplist(p_transform mytransform)2311 static void setkeeplist (p_transform mytransform)
2312 {
2313   if((mytransform->_callback==(void*)Xvalueof)     || (mytransform->_callback==(void*)Xifinsidep) || (mytransform->_callback==(void*)Xifnotinsidep) ||
2314      (mytransform->_callback==(void*)Xvaluetonull) || (mytransform->_callback==(void*)Xreset)     || (mytransform->_callback==(void*)Xreverse))
2315     mytransform->_pathselect->_keeplist=1;
2316   else if((mytransform->_callback==(void*)Xpush)||(mytransform->_callback==(void*)Xpushoncompare)||(mytransform->_callback==(void*)Xpushonduplicate))
2317     mytransform->_pathinto->_keeplist=1;
2318   else if((mytransform->_callback==(void*)Xifinsidepath) || (mytransform->_callback==(void*)Xifnotinsidepath))
2319     mytransform->_pathlist->_keeplist=1;
2320 }
2321 
xmlhook_start(const px xp)2322 static void xmlhook_start (const px xp)
2323 {
2324   int l=xp->l;
2325   const char* admstfile=xp->f;
2326   char* mybasename=basename(admstfile);
2327   p_slist Transform=root()->_transform;
2328   p_transform mytransform;
2329   struct sb* bp=xp->bp;
2330   const char* xname=bp->nom;
2331   if(!strcmp(xname,"admst"))
2332     mytransform=adms_transform_new(admstfile,mybasename,l,xname,NULL);
2333   else
2334   {
2335     p_transform parent=(p_transform)Transform->data;
2336     mytransform=adms_transform_new(admstfile,mybasename,l,xname,parent);
2337     if(T(admst:templates)||T(admst:template))
2338       adms_slist_push(&parent->_templates,(p_adms)mytransform);
2339     else
2340       adms_slist_push(&parent->_children,(p_adms)mytransform);
2341   }
2342   free(mybasename);
2343   adms_slist_push(&root()->_transform,(p_adms)mytransform);
2344   if(is_admst(xname))
2345   {
2346     for(bp->a=bp->a0;bp->a;bp->a=bp->a->X)
2347     {
2348       const char* aname=bp->a->nom;
2349       const char* avalue=xmltotxt(bp->a->valeur);
2350       if(((strlen(aname)==5)&&!strncmp(aname,"xmlns",5))||((strlen(aname)>5)&&!strncmp(aname,"xmlns:",6)))
2351       {}
2352       else if(!strcmp(aname,"arguments"))
2353       {
2354         p_slist myli=adms_strsplit(avalue,",",1000);
2355         p_slist myli0=myli;
2356         for(;myli;myli=myli->next)
2357           adms_slist_push(&mytransform->_textarguments,(p_adms)tparse(mytransform,aname,(char*)(myli->data)));
2358         adms_slist_inreverse(&mytransform->_textarguments);
2359         free_strlist(myli0);
2360       }
2361       else if(!strcmp(aname,"inputs"))
2362       {
2363         p_slist myli=adms_strsplit(avalue,",",1000);
2364         p_slist myli0=myli;
2365         for(;myli;myli=myli->next)
2366           adms_slist_push(&mytransform->_pathinputs,(p_adms)pparse(mytransform,aname,(char*)(myli->data)));
2367         adms_slist_inreverse(&mytransform->_pathinputs);
2368         free_strlist(myli0);
2369       }
2370       else if(!strcmp(aname,"oncompare"))
2371         mytransform->_pathoncompare=pparse(mytransform,aname,avalue);
2372       else if(!strcmp(aname,"test"))
2373         mytransform->_pathtest=pparse(mytransform,aname,avalue);
2374       else if(!strcmp(aname,"path"))
2375         mytransform->_pathpath=pparse(mytransform,aname,avalue);
2376       else if(!strcmp(aname,"into"))
2377         mytransform->_pathinto=pparse(mytransform,aname,avalue);
2378       else if(!strcmp(aname,"select"))
2379       {
2380         if(!strcmp(xname,"admst:variable"))
2381           mytransform->_textselect=tparse(mytransform,aname,avalue);
2382         else
2383           mytransform->_pathselect=pparse(mytransform,aname,avalue);
2384       }
2385       else if(!strcmp(aname,"string")||!strcmp(aname,"value"))
2386         mytransform->_textstring=tparse(mytransform,aname,avalue);
2387       else if(!strcmp(aname,"match"))
2388         mytransform->_textmatch=tparse(mytransform,aname,avalue);
2389       else if(!strcmp(aname,"required"))
2390         mytransform->_textrequired=tparse(mytransform,aname,avalue);
2391       else if(!strcmp(aname,"separator"))
2392         mytransform->_textseparator=tparse(mytransform,aname,avalue);
2393       else if(!strcmp(aname,"from"))
2394         mytransform->_textfrom=tparse(mytransform,aname,avalue);
2395       else if(!strcmp(aname,"to"))
2396         mytransform->_textto=tparse(mytransform,aname,avalue);
2397       else if(!strcmp(aname,"list"))
2398       {
2399         mytransform->_textlist=tparse(mytransform,aname,avalue);
2400         mytransform->_pathlist=(p_path)mytransform->_textlist->_token->data;
2401       }
2402       else if(!strcmp(aname,"name"))
2403         mytransform->_textname=tparse(mytransform,aname,avalue);
2404       else if(!strcmp(aname,"format"))
2405         mytransform->_textformat=tparse(mytransform,aname,avalue);
2406       else if(!strcmp(aname,"onduplicate"))
2407         mytransform->_textonduplicate=tparse(mytransform,aname,avalue);
2408       else if(!strcmp(aname,"file"))
2409         mytransform->_textfile=tparse(mytransform,aname,avalue);
2410       else if(!strcmp(aname,"version"))
2411         mytransform->_textversion=tparse(mytransform,aname,avalue);
2412       else if(!strcmp(aname,"datatype"))
2413         mytransform->_textdatatype=tparse(mytransform,aname,avalue);
2414       else if(!strcmp(aname,"mode"))
2415         adms_message_obsolete(("%s:%i: attribute %s=\"%s\" is ignored\n",admstfile,l,aname,avalue))
2416       else
2417         adms_message_fatal(("%s:%i: unknown attribute %s=\"%s\"\n",admstfile,l,aname,avalue))
2418     }
2419     setcallback(mytransform);
2420     return;
2421   }
2422   else
2423     mytransform->_callback=(void*)Xnotadmst,mytransform->_id="Xnotadmst";
2424   for(bp->a=bp->a0;bp->a;bp->a=bp->a->X)
2425   {
2426     const char* aname=bp->a->nom;
2427     const char* avalue=bp->a->valeur;
2428     p_attribute myattribute=adms_attribute_new(aname);
2429     myattribute->_value=(p_adms)tparse(mytransform,aname,avalue);
2430     adms_slist_push(&mytransform->_attribute,(p_adms)myattribute);
2431   }
2432   adms_slist_inreverse(&mytransform->_attribute);
2433 }
xmlhook_end(const px xp)2434 static void xmlhook_end (const px xp)
2435 {
2436   p_slist Transform=root()->_transform;
2437   p_transform mytransform=Transform?(p_transform)Transform->data:NULL;
2438   sanityxx (mytransform);
2439   if(is_admst(mytransform->_name))
2440     setkeeplist(mytransform);
2441   if(!T(admst))
2442     adms_slist_pull(&root()->_transform);
2443   adms_slist_inreverse(&mytransform->_children);
2444 }
2445  /*[nepasimprimer]*/
dbx(p_transform mytransform)2446 static void dbx (p_transform mytransform)
2447 {
2448   p_slist myli;
2449   adms_message_admstdbg_impl("<%s file=\"%s\">\n",mytransform->_id,adms_transform_uid(mytransform));
2450   dbxx(mytransform);
2451   for(myli=mytransform->_templates;myli;myli=myli->next)
2452     dbx((p_transform)myli->data);
2453   for(myli=mytransform->_children;myli;myli=myli->next)
2454     dbx((p_transform)myli->data);
2455   adms_message_admstdbg_impl("</%s>\n",mytransform->_id);
2456 }
2457 /*SNT becomes T
2458 static const char* text_excluding_leadingspaces (const char* text)
2459 {
2460   const char* cPtr=text;
2461   while(*cPtr&&isspace(*cPtr))
2462     cPtr++;
2463   if(*cPtr&&(*cPtr=='\n' || *cPtr=='\r'))
2464     cPtr++;
2465   return cPtr;
2466 }
2467 */
2468 /*[TNS]NS becomes [TNS]N */
text_excluding_trailingspaces(const char * text)2469 static char* text_excluding_trailingspaces (const char* text)
2470 {
2471   const char* cPtr=text;
2472   const char* nl=NULL;
2473   int t=0;
2474   int space=0;
2475   while(*cPtr)
2476   {
2477     if(!isspace(*cPtr))
2478     {t=1; space=0;}
2479     if(t&&(*cPtr=='\n' || *cPtr=='\r'))
2480     {nl=cPtr; space=0;}
2481     if(nl&&(*cPtr=='\n' || *cPtr=='\r'))
2482       space=1;
2483     cPtr++;
2484   }
2485   if(t&&space)
2486     return adms_knclone(text,nl-text);
2487   else if(t)
2488     return adms_kclone(text);
2489   else
2490     return NULL;
2491 }
xmlhook_text(const px xp)2492 static void xmlhook_text (const px xp)
2493 {
2494   const char* text=xmltotxt(xp->contenu);
2495   char* newtext=text_excluding_trailingspaces(text);
2496   if(root()->_transform&&newtext)
2497   {
2498     p_transform parent=(p_transform)root()->_transform->data;
2499     char* mybasename=basename(xp->f);
2500     p_transform mytransform=adms_transform_new(xp->f,mybasename,parent->_l,"admst:text",parent);
2501     free(mybasename);
2502     mytransform->_textformat=tparse(mytransform,"text()",newtext);
2503     mytransform->_callback=(void*)Xtext,mytransform->_id="Xtext";
2504     adms_slist_push(&parent->_children,(p_adms)mytransform);
2505   }
2506   free(newtext);
2507 }
2508  /*[nepasimprimer]*/
2509 #if defined(STANDALONE)
creearbrex(const char * xcode,const char * myadmstfile)2510 static void creearbrex(const char*xcode,const char*myadmstfile)
2511 #else
2512 static void creearbrex(const char*myadmstfile)
2513 #endif
2514 {
2515 #if defined(STANDALONE)
2516     char* xfile=adms_kclone(myadmstfile);
2517     char* xdata=adms_kclone(xcode);
2518 #else
2519 /*read xfile*/
2520     char* xfile=filename(myadmstfile);
2521     FILE*xxfh=fopen(xfile,"rb");
2522     char buf[1024];
2523     char *xdata=NULL;
2524     size_t readbytes=0;
2525     if(!xxfh)
2526       adms_message_fatal(("%s: failed to open file [read mode]\n",xfile))
2527     if(!adms_file_isregular(xfile))
2528       adms_message_fatal(("%s: cannot read file - perhaps binary file\n",xfile))
2529     while(!feof(xxfh))
2530     {
2531       size_t newreadbytes=fread(buf,sizeof(char),sizeof(buf),xxfh);
2532       if(ferror(xxfh))
2533         adms_message_fatal(("%s: failed to read file\n",xfile))
2534       if(!(xdata=(char*)realloc(xdata,readbytes+newreadbytes)))
2535         adms_message_fatal(("%s: not enough memory available to read the file\n",xfile))
2536       memcpy(xdata+readbytes,buf,newreadbytes);
2537       readbytes+=newreadbytes;
2538     }
2539     fclose(xxfh);
2540     xdata=(char*)realloc(xdata,readbytes+1);
2541     *(xdata+readbytes)='\0';
2542 #endif
2543     racine.Y0=NULL;
2544     racine.Y=NULL;
2545     arbre(xdata,myadmstfile);
2546     free(xdata);
2547     free(xfile);
2548 }
2549 #if defined(STANDALONE)
admsmain(const char * xcode,const char * xflag,const char * vafile)2550 int admsmain (const char*xcode,const char*xflag,const char*vafile)
2551 {
2552   int argc=3;
2553   const char**argv=malloc(sizeof(char*)*argc);
2554 #else
2555 static void xbackup (const char* xfile,FILE*xfh)
2556 {
2557   FILE*xxfh=fopen(xfile,"rb");
2558   char buf[1024];
2559   char *firstbyte=NULL;
2560   size_t readbytes=0;
2561   if(!xxfh)
2562     adms_message_fatal(("%s: failed to open file [read mode]\n",xfile))
2563   if(!adms_file_isregular(xfile))
2564     adms_message_fatal(("%s: cannot read file - perhaps binary file\n",xfile))
2565   while(!feof(xxfh))
2566   {
2567     size_t newreadbytes=fread(buf,sizeof(char),sizeof(buf),xxfh);
2568     if(ferror(xxfh))
2569       adms_message_fatal(("%s: failed to read file\n",xfile))
2570     if(!(firstbyte=(char*)realloc(firstbyte,readbytes+newreadbytes)))
2571       adms_message_fatal(("%s: not enough memory available to read the file\n",xfile))
2572     memcpy(firstbyte+readbytes,buf,newreadbytes);
2573     readbytes+=newreadbytes;
2574   }
2575   fclose(xxfh);
2576   firstbyte=(char*)realloc(firstbyte,readbytes+1);
2577   *(firstbyte+readbytes)='\0';
2578   fwrite(firstbyte,sizeof(char),readbytes,xfh);
2579   fflush(xfh);
2580   free(firstbyte);
2581 }
2582 int main (const int argc,const char**argv)
2583 {
2584 #endif
2585   char* myadmsimplicitxmlfile;
2586   char* mygetenv=getenv("adms_implicit_transforms");
2587   int myskipxmli=0;
2588   time_t mytime=time(NULL);
2589   p_slist myxargs;
2590   p_slist myli;
2591   FILE*xfh;
2592   char* xheader=NULL;
2593   const char* xinterface=".interface.xml";
2594 #if defined(STANDALONE)
2595   argv[0]=adms_kclone("admsXml");
2596   argv[1]=adms_kclone(xflag);
2597   argv[2]=adms_kclone(vafile);
2598 #endif
2599   /*NAN*/
2600   adms_NAN=adms_dzero/adms_dzero;
2601   /*admsmain*/
2602   rootnew(adms_admsmain_new("admsmain"));
2603   if(getenv("adms_info")    && !strcmp(getenv("adms_info"),    "no"))  root()->_info=admse_no;
2604   if(getenv("adms_usage")   && !strcmp(getenv("adms_usage"),   "no"))  root()->_usage=admse_no;
2605   if(getenv("adms_obsolete")&& !strcmp(getenv("adms_obsolete"),"no"))  root()->_obsolete=admse_no;
2606   if(getenv("adms_hint")    && !strcmp(getenv("adms_hint"),    "yes")) root()->_hint=admse_yes;
2607   if(getenv("adms_verbose") && !strcmp(getenv("adms_verbose"), "yes")) root()->_verbose=admse_yes;
2608   if(getenv("adms_debug")   && !strcmp(getenv("adms_debug"),   "yes")) root()->_debug=admse_yes;
2609   if(getenv("adms_dbg_vla") && !strcmp(getenv("adms_dbg_vla"), "yes")) root()->_dbg_vla=admse_yes;
2610   if(getenv("adms_dbg_xml") && !strcmp(getenv("adms_dbg_xml"), "yes")) root()->_dbg_xml=admse_yes;
2611   /*argc,argv*/
2612   {
2613     int i;
2614     root()->_argc=argc;
2615     root()->_argv=NULL;
2616     for(i=0;i<argc;i++)
2617     {
2618       if((strlen(argv[i])==2)&&!strcmp(argv[i],"-x"))
2619       {
2620         myskipxmli=1;
2621         adms_message_info(("-x: skipping any implicit xml scripts\n"))
2622       }
2623       else if((strlen(argv[i])==3)&&!strcmp(argv[i],"-xv"))
2624       {
2625         myskipversion=1;
2626         adms_message_info(("-xv: skipping version check\n"))
2627       }
2628       if((strlen(argv[i])==8)&&!strcmp(argv[i],"-compat2"))
2629         adms_message_warning(("backward compat ignored\n"))
2630       adms_slist_push(&root()->_argv,(p_adms)adms_kclone(argv[i]));
2631     }
2632   }
2633  /*[nepasimprimer]*/
2634 /*main.simulator*/
2635   {
2636     char* sfullname=NULL;
2637     adms_k2strconcat(&sfullname,PACKAGE_NAME);
2638     adms_k2strconcat(&sfullname,"Xml-");
2639     if(getenv("adms_check"))
2640       adms_k2strconcat(&sfullname,"0.0.0 (shell variable 'adms_check' is set!)");
2641     else
2642       adms_k2strconcat(&sfullname,PACKAGE_VERSION);
2643     root()->_simulator=adms_simulator_new(sfullname);
2644     root()->_simulator->_fullname=adms_kclone(sfullname);
2645   }
2646  /*[nepasimprimer]*/
2647 /*main.simulator.developer*/
2648   if(getenv("adms_check"))
2649     root()->_simulator->_developer=adms_kclone("0.0.0 (shell variable 'adms_check' is set)");
2650   else
2651   {
2652     char* sdeveloper=NULL;
2653     adms_k2strconcat(&sdeveloper,PACKAGE_NAME);
2654     adms_k2strconcat(&sdeveloper,"Xml");
2655     adms_k2strconcat(&sdeveloper,"-");
2656     adms_k2strconcat(&sdeveloper,PACKAGE_VERSION);
2657     adms_k2strconcat(&sdeveloper," (");
2658     adms_k2strconcat(&sdeveloper,__DATE__);
2659     adms_k2strconcat(&sdeveloper,"-");
2660     adms_k2strconcat(&sdeveloper,__TIME__);
2661     adms_k2strconcat(&sdeveloper,")");
2662     root()->_simulator->_developer=sdeveloper;
2663   }
2664  /*[nepasimprimer]*/
2665 /*main.simulator.currentdate*/
2666   if(getenv("adms_check"))
2667     root()->_simulator->_currentdate=adms_kclone("0.0.0 (shell variable 'adms_check' is set)\n");
2668   else
2669   {
2670     char mybuffer[100];
2671     struct tm* mylocaltime=localtime(&mytime);
2672     strftime (mybuffer,100,"%a, %d %b %Y %H:%M:%S",mylocaltime);
2673     root()->_simulator->_currentdate=adms_kclone(mybuffer);
2674   }
2675  /*[nepasimprimer]*/
2676 /*shell*/
2677   if(getenv("adms_dbg_pre"))
2678     adms_preprocessor_setint_yydebug(1);
2679   else
2680     adms_preprocessor_setint_yydebug(0);
2681  /*[nepasimprimer]*/
2682   if(
2683     (argc==1)
2684     ||
2685     ((argc==2)&&!strcmp(argv[1],"-h"))
2686     ||
2687     ((argc==2)&&!strcmp(argv[1],"--help"))
2688     ||
2689     ((argc==3)&&!strcmp(argv[1],"--")&&!strcmp(argv[2],"help"))
2690   )
2691   {
2692     adms_message_usage(("%sXml-%s (%s) ",PACKAGE_NAME,PACKAGE_VERSION,GIT))
2693     adms_message_usage_continue(("%s %s (os=%s compiler=%s)\n",__DATE__,__TIME__,ADMS_OS,ADMS_COMPILER))
2694     adms_message_usage(("%sXml source [options] -e script1 [-e script2 ...]\n",PACKAGE_NAME))
2695     adms_message_usage(("files:\n"))
2696     adms_message_usage(("  source: verilog-ams source code\n"))
2697     adms_message_usage(("  script1, ...: admst scripts (xml format)\n"))
2698     adms_message_usage(("options:\n"))
2699     adms_message_usage(("  -D NAME: predefine NAME as a macro, with definition `1'\n"))
2700     adms_message_usage(("  -D NAME=DEFINITION: predefine NAME as a macro, with definition DEFINITION\n"))
2701     adms_message_usage(("  -I DIR: Add directory DIR to search path for header files\n"))
2702     adms_message_usage(("  -x : ignore file .adms.implicit.xml\n"))
2703     adms_message_usage(("  -xv: do not check version number of scripts\n"))
2704     adms_message_usage(("shell variables:\n"))
2705     adms_message_usage(("- adms_info=\"yes\"|\"no\": print info [default=yes]\n"))
2706     adms_message_usage(("- adms_usage=\"yes\"|\"no\": print usage [default=yes]\n"))
2707     adms_message_usage(("- adms_verbose=\"yes\"|\"no\": print messages [default=no]\n"))
2708     adms_message_usage(("- adms_debug=\"yes\"|\"no\": print more messages [default=no]\n"))
2709     adms_message_usage(("- adms_dbg_vla=\"yes\"|\"no\": debug messages during vla parsing [default=no]\n"))
2710     adms_message_usage(("- adms_dbg_xml=\"yes\"|\"no\": debug messages during xml parsing [default=no]\n"))
2711     adms_message_usage(("- adms_dbg_pre=\"yes\"|\"no\": debug messages during vla preprocessing [default=no]\n"))
2712     adms_message_usage(("-i or --info: miscellaneous info (release, web site, mailing list)\n"))
2713     adms_message_usage(("-v or --version: version number\n"))
2714     adms_message_usage(("-h or --help: short help\n"))
2715   }
2716   else if(
2717     ((argc==2)&&!strcmp(argv[1],"-v"))
2718     ||
2719     ((argc==2)&&!strcmp(argv[1],"--version"))
2720     ||
2721     ((argc==3)&&!strcmp(argv[1],"--")&&!strcmp (argv[2],"version"))
2722   )
2723   {
2724     adms_message_usage(("<release name=\"%sXml\" version=\"%s\" date=\"%s\" time=\"%s\"/>\n",PACKAGE_NAME,PACKAGE_VERSION,__DATE__,__TIME__))
2725     return 0;
2726   }
2727   else if(
2728     ((argc==2)&&!strcmp(argv[1],"-i"))
2729     ||
2730     ((argc==2)&&!strcmp(argv[1],"--info"))
2731     ||
2732     ((argc==3)&&!strcmp(argv[1],"--")&&!strcmp(argv[2],"info"))
2733   )
2734   {
2735     adms_message_usage(("<info\n",PACKAGE_BUGREPORT))
2736     adms_message_usage(("  author=\"laurent lemaitre\"\n",PACKAGE_BUGREPORT))
2737     adms_message_usage(("  bug-report=\"%s\"\n",PACKAGE_BUGREPORT))
2738     adms_message_usage(("  home-page=\"https://sourceforge.net/projects/mot-adms/\"\n"))
2739     adms_message_usage(("  mailing-list=\"mot-adms-users@lists.sourceforge.net\">\n"))
2740     adms_message_usage(("  <release name=\"%s\" version=\"%s\" ",PACKAGE_NAME,PACKAGE_VERSION))
2741     adms_message_usage_continue(("git=\"%s\" date=\"%s\" time=\"%s\"/>\n",GIT,__DATE__,__TIME__))
2742     adms_message_usage(("</info>\n"))
2743     return 0;
2744   }
2745 /*create implicit admst script*/
2746   {
2747     if(mygetenv)
2748     {
2749       myadmsimplicitxmlfile=filename(mygetenv);
2750       adms_message_info(("loading implicit xml script %s\n",mygetenv))
2751       adms_message_info(("(shell variable 'adms_implicit_transforms' has been set)\n"))
2752     }
2753     else
2754     {
2755 #include "adms.implicit.xml.c"
2756       FILE*ofh;
2757       myadmsimplicitxmlfile=adms_kclone(".adms.implicit.xml");
2758       if(!(ofh=fopen(myadmsimplicitxmlfile,"wb")))
2759         adms_message_fatal(("%s: failed to open file [write mode]\n",myadmsimplicitxmlfile))
2760       fputs(adms_implicit_xml,ofh);
2761       fclose(ofh);
2762     }
2763   }
2764   if(
2765     (argc==1)
2766     ||
2767     ((argc==2)&&!strcmp(argv[1],"-h"))
2768     ||
2769     ((argc==2)&&!strcmp(argv[1],"--help"))
2770     ||
2771     ((argc==3)&&!strcmp(argv[1],"--")&&!strcmp(argv[2],"help"))
2772   )
2773     return 0;
2774  /*[nepasimprimer]*/
2775 /*parse verilogams list*/
2776   {
2777     p_slist l=getlist_from_argv(argc,argv,"-f","file");
2778     for(myli=l;myli;myli=myli->next)
2779       parseva(argc,argv,(char*)(myli->data));
2780     adms_slist_free(l);
2781   }
2782 /*add implicit admst script*/
2783   myxargs=getlist_from_argv(argc,argv,"-e","file");
2784 #if defined(STANDALONE)
2785   adms_slist_push(&myxargs,(p_adms)adms_kclone("stdin"));
2786 #endif
2787   adms_slist_push(&myxargs,(p_adms)myadmsimplicitxmlfile);
2788  /*[nepasimprimer]*/
2789 /*traverse scripts*/
2790   if(!(xfh=fopen(xinterface,"wb")))
2791     adms_message_fatal(("%s: failed to open file [write mode]\n",xinterface))
2792   adms_k2strconcat(&xheader,"<!--\n");
2793   adms_k2strconcat(&xheader,"  File automatically created\n");
2794   adms_k2strconcat(&xheader,"  Command used:\n");
2795   adms_k2strconcat(&xheader,"  # release: ");
2796   adms_k2strconcat(&xheader,PACKAGE_VERSION);
2797   adms_k2strconcat(&xheader," ");
2798   adms_k2strconcat(&xheader,__DATE__);
2799   adms_k2strconcat(&xheader,"-");
2800   adms_k2strconcat(&xheader,__TIME__);
2801   adms_k2strconcat(&xheader,"\n");
2802   adms_k2strconcat(&xheader,"  ");
2803   adms_k2strconcat(&xheader,PACKAGE_NAME);
2804   adms_k2strconcat(&xheader,"Xml");
2805   adms_k2strconcat(&xheader," \\\n");
2806   if(myskipxmli)
2807     adms_k2strconcat(&xheader,"   -x \\\n");
2808   for(myli=myxargs;myli;myli=myli->next)
2809     if(myli!=myxargs)
2810     {
2811       const char* myadmstfile=(char*)(myli->data);
2812       adms_k2strconcat(&xheader,"   -e ");
2813       adms_k2strconcat(&xheader,myadmstfile);
2814       if(myli->next)
2815         adms_k2strconcat(&xheader," \\");
2816       adms_k2strconcat(&xheader,"\n");
2817     }
2818   adms_k2strconcat(&xheader,"-->\n\n");
2819   fwrite(xheader,sizeof(char),strlen(xheader)*sizeof(char),xfh);
2820 #if defined(STANDALONE)
2821   fwrite(xcode,sizeof(char),strlen(xcode)*sizeof(char),xfh);
2822 #endif
2823   fflush(xfh);
2824   free(xheader);
2825 #if defined(STANDALONE)
2826 #else
2827   for(myli=myxargs;myli;myli=myli->next)
2828     if(!myskipxmli || myli!=myxargs)
2829     {
2830       const char* myadmstfile=(char*)(myli->data);
2831       char* xfile=filename(myadmstfile);
2832       char* xlocalheader=NULL;
2833       adms_k2strconcat(&xlocalheader,"\n");
2834       adms_k2strconcat(&xlocalheader,"<?escript name=\"");
2835       adms_k2strconcat(&xlocalheader,myadmstfile);
2836       adms_k2strconcat(&xlocalheader,"\" ?>\n");
2837       fwrite(xlocalheader,sizeof(char),strlen(xlocalheader)*sizeof(char),xfh);
2838       fflush(xfh);
2839       free(xlocalheader);
2840       xbackup(xfile,xfh);
2841       free(xfile);
2842     }
2843 #endif
2844   fclose(xfh);
2845 /*db*/
2846     if(root()->_dbg_xml==admse_yes)
2847     {
2848       p_slist l;
2849       char*mydbgfile1=".admst1.xml";
2850       char*mydbgfile2=".admst2.xml";
2851       const char*admstdtduri="http://mot-adms.svn.sourceforge.net/viewvc/mot-adms/trunk/adms/admst.dtd";
2852 #if defined(STANDALONE)
2853       creearbrex(xcode,".interface.xml");
2854 #else
2855       creearbrex(".interface.xml");
2856 #endif
2857       if(!(stdadmstdbgimpl=fopen(mydbgfile1,"wb")))
2858         adms_message_fatal(("%s: failed to open file [write mode]\n",mydbgfile1))
2859       adms_message_admstdbg_impl("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
2860       adms_message_admstdbg_impl("<!DOCTYPE admst PUBLIC \"-//adms//DTD admst 2.0//-\" \"%s\">\n",admstdtduri);
2861       adms_message_admstdbg_impl("<!-- xmllint -valid -noout %s -->\n",mydbgfile1);
2862       adms_message_admstdbg_impl("<admst xmlns:admst=\"%s\">\n",admstdtduri);
2863       racine.dbg(&racine);
2864       adms_message_admstdbg_impl("</admst>\n");
2865       fclose(stdadmstdbg);
2866       stdadmstdbgimpl=NULL;
2867       if(!(stdadmstdbgimpl=fopen(mydbgfile2,"wb")))
2868         adms_message_fatal(("%s: failed to open file [write mode]\n",mydbgfile2))
2869       adms_message_admstdbg_impl("<admst>\n");
2870       for(l=root()->_transform;l;l=l->next)
2871         dbx((p_transform)l->data);
2872       adms_message_admstdbg_impl("</admst>\n");
2873       fclose(stdadmstdbg);
2874       stdadmstdbgimpl=NULL;
2875       adms_message_info(("%s, %s: debug files created (note: shell variable 'adms_dbg_xml' is set)\n",mydbgfile1,mydbgfile2))
2876     }
2877  /*[nepasimprimer]*/
2878   for(myli=myxargs;myli;myli=myli->next)
2879     if(!myskipxmli || myli!=myxargs)
2880     {
2881       p_slist l;
2882 #if defined(STANDALONE)
2883       creearbrex(xcode,(char*)myli->data);
2884 #else
2885       creearbrex((char*)myli->data);
2886 #endif
2887       adms_message_verbose(("-e file: %s\n",(char*)myli->data))
2888       racine.adms(&racine);
2889       if(root()->_dbg_xml==admse_yes)
2890       {
2891         char*mydbgfile=NULL;
2892         char* mybasename=basename((char*)myli->data);
2893         adms_k2strconcat(&mydbgfile,".");
2894         adms_k2strconcat(&mydbgfile,mybasename);
2895         if(!(stdadmstdbgimpl=fopen(mydbgfile,"wb")))
2896           adms_message_fatal(("%s: failed to open file [write mode]\n",mydbgfile))
2897         racine.dbg(&racine);
2898         free(mydbgfile);
2899         free(mybasename);
2900       }
2901       adms_message_verbose(("traverse: %s\n",(char*)myli->data))
2902       adms_slist_inreverse(&root()->_transform);
2903   /*postx*/
2904       for(l=root()->_transform;l;l=l->next)
2905         postx((p_transform)l->data);
2906   /*traverse*/
2907       for(l=root()->_transform;l;l=l->next)
2908         adms_slist_push(&root()->_invtransform,l->data);
2909       for(l=root()->_transform;l;l=l->next)
2910       {
2911         p_transform mytransform=(p_transform)l->data;
2912         p_admst myadmst=adms_admst_newpa(NULL,NULL,(p_adms)root());
2913         Xadmst(mytransform,myadmst,NULL);
2914         deref(myadmst);
2915       }
2916       if(root()->_valueof)
2917       {
2918         p_transform mytransform=(p_transform)root()->_valueof->data;
2919         adms_message_fatal_continue(("stack '%%s' is not empty! (%i element(s) left)\n",adms_slist_length(root()->_valueof)/2))
2920         adms_message_fatal(("see %s\n",adms_transform_uid(mytransform)))
2921       }
2922       adms_slist_free(root()->_transform);
2923       root()->_transform=NULL;
2924       free(myli->data);
2925     }
2926   adms_slist_free(root()->_invtransform);
2927   adms_message_verbose(("%s: file created (all -e files in one file)\n",xinterface))
2928   for(myli=root()->_variable;myli;myli=myli->next)
2929   {
2930     p_admstvariable dollar=(p_admstvariable)myli->data;
2931     p_slist l;
2932     for(l=dollar->_value;l;l=l->next)
2933     {
2934       ((p_admst)l->data)->_refd--;
2935       deref((p_admst)l->data);
2936     }
2937     adms_admstvariable_free(dollar);
2938   }
2939   adms_slist_free(myxargs);
2940  /*[nepasimprimer]*/
2941   adms_message_info(("elapsed time: %g (second)\n",difftime(time(NULL),mytime)))
2942   adms_message_info(("admst iterations: %i (%i freed)\n",adms_global_nbadmstnew(),adms_global_nbadmstdestroy()))
2943   return 0;
2944 }
2945 #if defined (STANDALONE) && defined (APATHMAIN)
2946 int main (int argc,char **argv)
2947 {
2948   return apath_main (argc,argv);
2949 }
2950 #endif
2951