#!perl -W use warnings; my $top_srcdir=shift @ARGV; die if not $top_srcdir; my$BUILDER="code automatically created by $0"; require "$top_srcdir/scripts/adms_build.libpl"; my$UNIQUE; $UNIQUE.="quark|enumeration|attribute"; #admsmain $UNIQUE.="|simulator|filename"; my$SVN; my$cygpath_top_srcdir=$top_srcdir; if($cygpath_top_srcdir=`cygpath -ad $top_srcdir 2>/dev/null`) { chomp $cygpath_top_srcdir; $cygpath_top_srcdir="\"$cygpath_top_srcdir\""; } $SVN=`svnversion -n $cygpath_top_srcdir 2>/dev/null` or $SVN="unknown"; sub buildenumerationname { my$elementname=shift; my$attributename=shift; my$v=shift; $v =~ s/-/_m/; return "adms_${elementname}_enumeration_${attributename}_${v}"; } sub buildsymbolname { my($attribute,$method)=(shift,shift,shift); return join"_",("adms",&element_name($attribute),$method,&attribute_name($attribute)); } sub buildsupersymbolname { my($element,$parent,$method)=(shift,shift,shift); return join"_",("adms",$element->getAttribute("name"),$method,$parent->getAttribute("name")); } # implement attribute_datatypefamily/attribute_datatypename sub attribute_datatypenameImpl { my$attribute=shift; my$element_name=&element_name($attribute); my$attributedatatypefamily=&attribute_datatypefamily($attribute); my$attributename=&attribute_name($attribute); my$attributedatatypename=&attribute_datatypename($attribute); my$attrTypeImpl; if(${attributedatatypefamily} eq "basicpointer") { if(${attributedatatypename} eq "quark") {$attrTypeImpl="const char*"} elsif(${attributedatatypename} eq "void") {$attrTypeImpl="void*"} elsif(${attributedatatypename} eq "list") {$attrTypeImpl="p_slist*"} elsif(${attributedatatypename} eq "base:character:array") {$attrTypeImpl="char**"} } elsif(${attributedatatypefamily} eq "basictype") { if(${attributedatatypename} eq "base:integer") {$attrTypeImpl="int"} elsif(${attributedatatypename} eq "base:enumeration") {$attrTypeImpl="e_${element_name}_${attributename}"} elsif(${attributedatatypename} eq "base:real") {$attrTypeImpl="double"} elsif(${attributedatatypename} eq "base:character:array") {$attrTypeImpl="char*"} } elsif(${attributedatatypefamily} eq "reference") { if(${attributedatatypename} eq "*") {$attrTypeImpl="p_adms"} else{$attrTypeImpl="p_${attributedatatypename}"} } else {die;} return $attrTypeImpl; } sub containerTypeImpl { my$attribute=shift; return (&attribute_size($attribute) eq "list")?"p_slist":&attribute_datatypenameImpl($attribute); } # build method templates for each attribute my$FUNCPREFIX="adms_ELTNAME_list_ATTRNAME"; my$LISTNAME="adms_ELTNAME_valueof_ATTRNAME(mymyELTNAME)"; my$templates={ reference_prepend_by_id_once_or_passthrough=>qq# H win32_interface ATTRCONTAINER ${FUNCPREFIX}_prepend_by_id_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRID_H); C ATTRCONTAINER C ${FUNCPREFIX}_prepend_by_id_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRID_H) C { C ATTRCONTAINER refATTRNAME=adms_ATTRVAL_new(ATTRID_C); C adms_slist_push(&$LISTNAME,adms_adms(refATTRNAME)); C return refATTRNAME; C } C #, reference_prepend_once_or_passthrough=>qq# H win32_interface void ${FUNCPREFIX}_prepend (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C } C #, reference_prepend_by_id=>qq# H win32_interface ATTRCONTAINER ${FUNCPREFIX}_prepend_by_id (p_ELTNAME mymyELTNAME,ATTRID_H); C ATTRCONTAINER C ${FUNCPREFIX}_prepend_by_id (p_ELTNAME mymyELTNAME,ATTRID_H) C { C ATTRCONTAINER refATTRNAME=adms_ATTRVAL_new(ATTRID_C); C adms_slist_push(&$LISTNAME,adms_adms(refATTRNAME)); C return refATTRNAME; C } C #, reference_prepend_by_id_once_or_ignore=>qq# H win32_interface ATTRCONTAINER ${FUNCPREFIX}_prepend_by_id_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRID_H); C ATTRCONTAINER C ${FUNCPREFIX}_prepend_by_id_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRID_H) C { C p_slist list=$LISTNAME; C ATTRCONTAINER refATTRNAME=adms_ATTRVAL_new(ATTRID_C); C while(list) C { C if(!adms_ATTRVAL_cmp(adms_ATTRVAL(list->data),refATTRNAME)) C { C adms_ATTRVAL_free (refATTRNAME); C return adms_ATTRVAL(list->data); C } C list=list->next; C } C adms_slist_push(&$LISTNAME,adms_adms(refATTRNAME)); C return refATTRNAME; C } C #, reference_prepend_by_id_once_or_abort=>qq# H win32_interface ATTRCONTAINER ${FUNCPREFIX}_prepend_by_id_once_or_abort (p_ELTNAME mymyELTNAME,ATTRID_H); C ATTRCONTAINER C ${FUNCPREFIX}_prepend_by_id_once_or_abort (p_ELTNAME mymyELTNAME,ATTRID_H) C { C p_slist list=$LISTNAME; C ATTRCONTAINER refATTRNAME=adms_ATTRVAL_new(ATTRID_C); C while(list) C { C if(!adms_ATTRVAL_cmp(adms_ATTRVAL(list->data),refATTRNAME)) C { C adms_message_fatal(("ELTNAME=[%s] ATTRNAME=[%s] already defined\\n", C adms_ELTNAME_uid(mymyELTNAME),adms_ATTRVAL_uid(refATTRNAME))) C adms_ATTRVAL_free (refATTRNAME); C } C list=list->next; C } C adms_slist_push(&$LISTNAME,adms_adms(refATTRNAME)); C return refATTRNAME; C } C #, reference_prepend_once_or_ignore=>qq# H win32_interface void ${FUNCPREFIX}_prepend_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C p_slist list=$LISTNAME; C while(list) C { C if(!adms_ATTRVAL_cmp(adms_ATTRVAL(list->data),myATTRNAME)) C return; C list=list->next; C } C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C } C #, reference_prepend_once_or_abort=>qq# H win32_interface void ${FUNCPREFIX}_prepend_once_or_abort (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend_once_or_abort (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C p_slist list=$LISTNAME; C while(list) C { C if(!adms_ATTRVAL_cmp(adms_ATTRVAL(list->data),myATTRNAME)) C { C adms_message_fatal(("ELTNAME=[%s] ATTRNAME=[%s] already defined\\n", C adms_ELTNAME_uid(mymyELTNAME),adms_ATTRVAL_uid(myATTRNAME))) C return; C } C list=list->next; C } C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C } C #, basictype_prepend_once_or_ignore=>qq# H win32_interface void ${FUNCPREFIX}_prepend_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend_once_or_ignore (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C if(!adms_slist_find($LISTNAME,adms_adms(myATTRNAME))) C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C } C #, basictype_prepend_once_or_abort=>qq# H win32_interface void ${FUNCPREFIX}_prepend_once_or_abort (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend_once_or_abort (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C if(!adms_slist_find($LISTNAME,adms_adms(myATTRNAME))) C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C else C adms_message_fatal(("ELTNAME=[%s] ATTRNAME=[%s] already defined\\n",adms_ELTNAME_uid(mymyELTNAME),myATTRNAME)) C } C #, basictype_prepend_by_id=>qq# H win32_interface void ${FUNCPREFIX}_prepend_by_id (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME); C void C ${FUNCPREFIX}_prepend_by_id (p_ELTNAME mymyELTNAME,ATTRCONTAINER myATTRNAME) C { C adms_slist_push(&$LISTNAME,adms_adms(myATTRNAME)); C } C # }; my$admsParser=XML::LibXML->new->parse_file ("$top_srcdir/adms.xml"); my($myElementArray,$myElementHash)=&parserXml($admsParser); foreach(@$myElementArray) {&mkNew($_);&mkNewimpl($_);&mkFree($_);} foreach(@$myElementArray) {&mkCode($_)} foreach("") {&mkCode($_)} #for objectClass #template for file naming: module -> objectModule sub makeFileName { my$name=shift; $name=~s/^(.)/object\U$1/; return $name; } #template for macro adms_..._free sub mkFree () { my$element=$_; my@attribute=&element_attribute($element); my$elementname=$element->getAttribute("name"); my$Hdec; my$Cdec; my@arguments; my$i=0; $FREE{$elementname}{H}.="win32_interface inline void adms_${elementname}_free(p_$elementname my$elementname);\n"; $FREE{$elementname}{C}.="inline void adms_${elementname}_free(p_$elementname my$elementname)\n"; $FREE{$elementname}{C}.="{\n"; $FREE{$elementname}{C}.=" if(!my$elementname)\n"; $FREE{$elementname}{C}.=" return;\n"; my$parent=$element; if($parent=&element_parent($parent)) { my$attributename=$parent->getAttribute("name"); if($attributename eq "subexpression") { $FREE{$elementname}{C}.=" adms_enumeration_free(my$elementname->_subexpression._math._dependency);\n"; $FREE{$elementname}{C}.=" free(my$elementname->_subexpression._math._value);\n"; } elsif($attributename eq "math") { $FREE{$elementname}{C}.=" adms_enumeration_free(my$elementname->_math._dependency);\n"; $FREE{$elementname}{C}.=" free(my$elementname->_math._value);\n"; } } foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributesize=&attribute_size($_); my$attributedatatypename=&attribute_datatypename($_); if(${attributesize} eq "scalar") {} elsif(${attributesize} eq "list") { if((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) { $FREE{$elementname}{C}.=" {p_slist l=my$elementname->_${attributename};for(;l;l=l->next) free(l->data);}\n"; } elsif(${attributedatatypefamily} eq "reference") { if(${attributedatatypename}=~$UNIQUE) { $FREE{$elementname}{C}.=" {p_slist l=my$elementname->_${attributename};for(;l;l=l->next) adms_${attributedatatypename}_free(adms_${attributedatatypename}(l->data));}\n"; } elsif(($elementname =~ "admsttext")&&($attributename =~ "token")) { $FREE{$elementname}{C}.=" {\n"; $FREE{$elementname}{C}.=" p_slist myl=my$elementname->_${attributename};for(;myl;myl=myl->next)\n"; $FREE{$elementname}{C}.=" {\n"; $FREE{$elementname}{C}.=" p_adms myadms=myl->data;\n"; $FREE{$elementname}{C}.=" if(myadms->_datatypename==adms_adms_enumeration_datatypename_quark)\n"; $FREE{$elementname}{C}.=" adms_quark_free(adms_quark(myadms));\n"; $FREE{$elementname}{C}.=" else if(myadms->_datatypename==adms_adms_enumeration_datatypename_admsttext)\n"; $FREE{$elementname}{C}.=" adms_admsttext_free(adms_admsttext(myadms));\n"; $FREE{$elementname}{C}.=" /*fixme\n"; $FREE{$elementname}{C}.=" else if(myadms->_datatypename==adms_adms_enumeration_datatypename_admstpath)\n"; $FREE{$elementname}{C}.=" */\n"; $FREE{$elementname}{C}.=" }\n"; $FREE{$elementname}{C}.=" }\n"; } } $FREE{$elementname}{C}.=" adms_slist_free(my$elementname->_${attributename});\n"; } } foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributesize=&attribute_size($_); my$attributedatatypename=&attribute_datatypename($_); if(${attributesize} eq "scalar") { if((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) { $FREE{$elementname}{C}.=" free(my$elementname->_${attributename});\n"; } elsif(${attributedatatypefamily} eq "reference") { if(${attributedatatypename}=~$UNIQUE) { $FREE{$elementname}{C}.=" adms_${attributedatatypename}_free(my$elementname->_${attributename});\n"; } elsif(${attributedatatypename} eq "*") { $FREE{$elementname}{C}.=" if(my$elementname->_${attributename})\n"; $FREE{$elementname}{C}.=" if(adms_adms(my$elementname->_${attributename})->_datatypename==adms_adms_enumeration_datatypename_quark)\n"; $FREE{$elementname}{C}.=" adms_quark_free(adms_quark(my$elementname->_${attributename}));\n"; } } } } $FREE{$elementname}{C}.=" adms_global_increment_nb${elementname}destroy();\n" if $elementname ne "admsmain"; $FREE{$elementname}{C}.=" free(my$elementname);\n"; $FREE{$elementname}{C}.="}\n"; } #template for adms_..._new_impl sub mkNewimpl () { my$element=$_; my@attribute=&element_attribute($element); my$elementname=$element->getAttribute("name"); my$Hdec; my$Cdec; my@arguments; my$i=0; $NEWimpl{$elementname}{C}.="p_adms adms_${elementname}_new_impl (p_adms arguments[])\n"; $NEWimpl{$elementname}{C}.="{\n"; $NEWimpl{$elementname}{C}.=" p_${elementname} mynew${elementname};\n"; foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); my$isuid=&isuid($_); if($isuid) { my$attributedatatypenameImpl=&attribute_datatypenameImpl($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); if((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) {$NEWimpl{$elementname}{C}.=" const ${attributedatatypenameImpl} my$attributename=(${attributedatatypenameImpl})arguments[$i];\n";} elsif((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:integer")) {$NEWimpl{$elementname}{C}.=" const ${attributedatatypenameImpl} my$attributename=ADMS2INT(arguments[$i]);\n";} elsif((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:real")) {$NEWimpl{$elementname}{C}.=" ${attributedatatypenameImpl} my$attributename=atof((char*)arguments[$i]);\n";} elsif((${attributedatatypefamily} eq "reference")&&(${attributedatatypename} eq "quark")) {$NEWimpl{$elementname}{C}.=" ${attributedatatypenameImpl} my$attributename=adms_quark_new((char*)arguments[$i]);\n";} else {$NEWimpl{$elementname}{C}.=" ${attributedatatypenameImpl} my$attributename=(${attributedatatypenameImpl})arguments[$i];\n";} push @arguments,"my$attributename"; $i++; } } $NEWimpl{$elementname}{C}.=" mynew${elementname}=adms_${elementname}_new(".(join",",@arguments).");\n"; $NEWimpl{$elementname}{C}.=" return adms_adms(mynew${elementname});\n"; $NEWimpl{$elementname}{C}.="}\n"; $NEWimpl{$elementname}{H}.="p_adms adms_${elementname}_new_impl (p_adms arguments[])"; } #template for adms_..._new sub mkNew () { my$element=$_; my@attribute=&element_attribute($element); my$elementname=$element->getAttribute("name"); my$Hcode; my$Ccode; my$args; foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); my$isuid=&isuid($_); if($isuid) { my$attributedatatypenameImpl=&attribute_datatypenameImpl($_); if((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) {push @$Hcode,"const ${attributedatatypenameImpl} my$attributename";} else {push @$Hcode,"${attributedatatypenameImpl} my$attributename";} push @$Ccode,"my$attributename"; push @$args,"my$attributename"; } } $NEW{$elementname}{Cdec}=(join ",",@$Ccode); $NEW{$elementname}{Hdec}=(join ",",@$Hcode); $NEW{$elementname}{dec}= "p_$elementname adms_${elementname}_new(".($NEW{${elementname}}{Hdec}).")"; $NEW{$elementname}{args}=join",",@$args; } sub mkCode () { my$element=shift; my$elementname=$element?$element->getAttribute("name"):"class"; my @C; unlink "${top_srcdir}/admsObject/".makeFileName($elementname).".c"; unlink "${top_srcdir}/admsObject/".makeFileName($elementname).".h"; if($elementname eq "class") { my @admsH_H; push @admsH_H,"\n/* ------- $BUILDER -------------- */\n"; push @admsH_H,"\n"; push @admsH_H,"#define SVN \"${SVN }\" /* svn release version */\n"; push @admsH_H,q@ /*headers -- depend on compiler, OS, ...*/ # include # if defined(_MSC_VER) # define PACKAGE_NAME "adms" # define PACKAGE_STRING "adms 2.2.7" # define PACKAGE_TARNAME "adms" # define PACKAGE_VERSION "2.2.7" # define PACKAGE_BUGREPORT "r29173\@users.sourceforge.net" # include # define isnan _isnan # define adms_NAN sqrt(-1.0) # define ADMS_PATH_SEPARATOR "\\\\" # define ADMS_F_OK 0 # ifndef inline # define inline # endif # define HAVE_FLOAT_H 1 # define HAVE_STDLIB_H 1 # define HAVE_PUTENV 1 # define HAVE_LOCALE 1 # define HAVE_STRING_H 1 # define HAVE_SYS_STAT_H 1 # else # include # define adms_NAN (0.0/0.0) # define ADMS_PATH_SEPARATOR "/" # include # define ADMS_F_OK F_OK # endif # include # if defined(HAVE_SYS_STAT_H) # include # endif # if defined(HAVE_LOCALE_H) # include # endif # if defined(HAVE_FLOAT_H) # include # endif # if defined(HAVE_UNISTD_H) # include # endif # if defined(HAVE_STDLIB_H) # include # endif # if defined(HAVE_STRING_H) # include # endif # include # include # include # include # include # include # include /* in case not Posix */ # if defined(_S_IFDIR) # define ADMS_S_IFDIR _S_IFDIR # else # define ADMS_S_IFDIR S_IFDIR # endif /* check OS */ # if defined(__CYGWIN__) # define ADMS_OS_MS # define ADMS_OS_MSCYGWIN # define ADMS_OS "MSCYGWIN" # elif defined(__MSDOS__) # define ADMS_OS_MS # define ADMS_OS_MSDOS # define ADMS_OS "MSDOS" # elif defined(_WIN64) # define ADMS_OS_MS # define ADMS_OS_MSWIN64 # define ADMS_OS "MSWIN64" # elif defined(_WIN32) # define ADMS_OS_MS # define ADMS_OS_MSWIN32 # define ADMS_OS "MSWIN32" # else # define ADMS_OS_UNKNOWN # define ADMS_OS "UNKNOWN" # endif /* check compiler */ # if defined(__MINGW32__) # ifndef WIN32 # define WIN32 # endif # define ADMS_COMPILER_MINGCC # define ADMS_COMPILER "MINGCC" # elif defined(__CYGWIN__) # ifndef WIN32 # define WIN32 # endif # define ADMS_COMPILER_GCC # define ADMS_COMPILER "GCC" # elif defined(_MSC_VER) # ifndef WIN32 # define WIN32 # endif # define ADMS_COMPILER_MSVC # define ADMS_COMPILER "MSVC" # else # define ADMS_COMPILER_CC # define ADMS_COMPILER "CC" # endif @; push @admsH_H,"\n"; push @admsH_H,"#ifndef object${elementname}_h\n"; push @admsH_H,"#define object${elementname}_h\n"; push @admsH_H,"\n"; push @admsH_H,"#undef win32_interface\n"; push @admsH_H,"#if defined(WIN32)\n"; push @admsH_H,"# if defined(_inside_admsObject)\n"; push @admsH_H,"# define win32_interface __declspec(dllexport)\n"; push @admsH_H,"# else\n"; push @admsH_H,"# define win32_interface __declspec(dllimport)\n"; push @admsH_H,"# endif\n"; push @admsH_H,"#else\n"; push @admsH_H,"# define win32_interface extern\n"; push @admsH_H,"#endif\n"; push @admsH_H,"#define ADMS2INT(a) ((int)(long)(a))\n"; push @admsH_H,"#define INT2ADMS(a) ((p_adms)(long)(a))\n"; push @admsH_H,"\n"; foreach(@$myElementArray) { my$element=$_; my$elementname=$element->getAttribute("name"); push @admsH_H,"typedef struct s_$elementname t_$elementname;\n"; push @admsH_H,"typedef t_$elementname* p_$elementname;\n"; } my($codeH,$codeC)=&miscellaneous_code; push @admsH_H,$codeH; push @admsH_H,"#endif /* object${elementname}_h */\n"; open FILE,">${top_srcdir}/admsObject/admsH.h"; print FILE (join "",@admsH_H); close FILE; my@admsC_H; push @admsC_H,"\n/* ------- $BUILDER -------------- */\n"; push @admsC_H,"\n"; push @admsC_H,"#ifndef adms_h\n"; push @admsC_H,"#define adms_h\n"; push @admsC_H,"\n"; push @admsC_H,"#include \n"; foreach(@$myElementArray) { my$element=$_; my $elementname=$element->getAttribute("name"); push @admsC_H,"#include \n"; } push @admsC_H,"#endif /* adms_h */\n"; open FILE,">${top_srcdir}/admsObject/admsC.h"; print FILE (join "",(@admsC_H)); close FILE; } else { my @H; push @H,"\n/* ------- $BUILDER -------------- */\n"; push @H,"\n"; push @H,"#ifndef object${elementname}_h\n"; push @H,"#define object${elementname}_h\n"; push @H,"#include \n"; my$parent=&element_parent($element); if($parent) { my$parentName=$parent->getAttribute ("name"); push @H,"#include \n"; } my$hEnum=&gettor_attribute_enumeration ($element,"h"); push @H,$hEnum if $hEnum; push @H,&mkElementStructure($element); my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); my$isuid=&isuid($_); if((${attributedatatypefamily} eq "reference")&&(${attributedatatypename} ne "*")) { push @H,"#include \n" if not $Halreadyin{$elementname}{${attributedatatypename}}; $Halreadyin{$elementname}{${attributedatatypename}}=1; } } push @H,"\n"; push @H,"#undef win32_interface\n"; push @H,"#if defined(WIN32)\n"; push @H,"# if defined(_inside_admsObject)\n"; push @H,"# define win32_interface __declspec(dllexport)\n"; push @H,"# else\n"; push @H,"# define win32_interface __declspec(dllimport)\n"; push @H,"# endif\n"; push @H,"#else\n"; push @H,"# define win32_interface extern\n"; push @H,"#endif\n"; push @H,"\n"; push @H,"win32_interface char*adms_${elementname}_uid (p_$elementname my$elementname);\n"; push @H,"win32_interface int adms_${elementname}_cmp (p_$elementname my$elementname,p_$elementname ref$elementname);\n"; push @H,"win32_interface ".$NEW{$elementname}{dec}.";\n" if($elementname ne "adms"); push @H,"win32_interface ".$NEWimpl{$elementname}{H}.";\n"; push @H,"#define adms_$elementname(member) ((p_$elementname) (member))\n"; push @H,&mkAttributeValueof($element,"h"); push @H,&mkAttributeValueto($element,"h"); push @C,"\n/* ------- $BUILDER -------------- */\n"; push @C,"#include \n"; push @C,"#include \n"; push @C,"\n"; push @H,$FREE{$elementname}{H}; push @C,$FREE{$elementname}{C}; push @C,&mkElementCmp($element); push @C,&mkElementNew($element) if($elementname ne "adms"); push @C,&mkAttributeValueof($element,"c"); push @C,&mkAttributeValueto($element,"c"); my$cEnum=&gettor_attribute_enumeration ($element,"c"); push @C,$cEnum if $cEnum; if($elementname eq "admsttransform") { my($codeH,$codeC)=&miscellaneous_code; push @C,$codeC; push @C,&build_admsxml_allattribute; ($codeH,$codeC)=&build_admsxml_accessors; push @H,$codeH; push @C,$codeC; } push @H,"#endif /* object${elementname}_h */\n"; open FILE,">${top_srcdir}/admsObject/".makeFileName($elementname).".h"; print FILE (join "",(@H)); close FILE; open FILE,">${top_srcdir}/admsObject/".makeFileName($elementname).".c"; print FILE (join "",(@C)); close FILE; } } sub mkElementStructure () { my$element=$_; my$elementname=$element->getAttribute("name"); my$structure.="struct s_$elementname {\n"; my$parent=&element_parent($element); if($parent) { my$parentName=$parent->getAttribute ("name"); $structure.=" t_$parentName _$parentName;\n"; } my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$containerTypeImpl=&containerTypeImpl($_); $structure.=" $containerTypeImpl "."_${attributename};\n"; $structure.=" int _${attributename}_isdefault : 1;\n"; } $structure.="};\n"; return $structure; } sub mkAttributeValueof () { my$element=shift; my$type=shift; my$elementname=$element->getAttribute("name"); my$Hcode; my$Ccode; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypename=&attribute_datatypename($_); my$containerTypeImpl=&containerTypeImpl($_); my$valueof=&buildsymbolname($_,"valueof"); my$isdefault=&buildsymbolname($_,"isdefault"); $Ccode.=""; $Hcode.="#define $isdefault($elementname) (adms_$elementname($elementname)->_${attributename}_isdefault)\n"; $Hcode.="#define $valueof($elementname) (adms_$elementname($elementname)->_${attributename})\n"; } my$parent=$element; while($parent=&element_parent($parent)) { my$parentName=$parent->getAttribute ("name"); my$attributename=$parentName; my$containerTypeImpl="p_adms"; my$valueof=&buildsupersymbolname($element,$parent,"valueof"); $Hcode.="#define $valueof($elementname) ((p_$parentName)$elementname)\n"; } return $Hcode if($type eq "h"); return $Ccode if($type eq "c"); } sub gettor_attribute_enumeration () { my$element=shift; my$type=shift; my$elementname=$element->getAttribute("name"); my$Hcode; my$Ccode; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypename=&attribute_datatypename($_); my$attributedatatypefamily=&attribute_datatypefamily($_); if((${attributedatatypename} eq "base:enumeration")||(${attributedatatypename} eq "enumeration")) { my$attributedatatypenameImpl=&attribute_datatypenameImpl($_); my$evalue=&evalue($_); $Hcode.="typedef enum {\n"; my@Henum; my$i=0; foreach $v (sort @$evalue) { push @Henum," ".buildenumerationname($elementname,$attributename,$v); $i++; } $Hcode.=join ",\n", @Henum; $Hcode.="\n} e_${elementname}_${attributename};\n"; $Ccode.="e_${elementname}_${attributename}\n".&buildsymbolname($_,"fromstring")."_impl (p_admsttransform myadmsttransform,char*token)\n"; $Ccode.="{\n"; foreach $v (sort @$evalue) { my$v_lc=lc $v; $Ccode.=" if(!strcmp(token,\"$v\"))\n"; $Ccode.=" return ".buildenumerationname($elementname,$attributename,$v).";\n"; } $Ccode.=" adms_message_fatal_continue((\"select='${elementname}/${attributename}': possible values:\\n\"))\n"; $Ccode.=" adms_message_fatal_continue((\"" . join("|",sort @$evalue) ."\\n\"))\n"; $Ccode.=" adms_message_fatal((\"see %s\\n\",adms_admsttransform_uid(myadmsttransform)))\n"; $Ccode.=" return 0;\n"; $Ccode.="}\n"; if(${attributedatatypefamily} eq "reference") { $Ccode.="char*\n".&buildsymbolname($_,"tostring")."_impl (p_admsttransform myadmsttransform,p_enumeration myenumeration)\n"; $Ccode.="{\n"; $Ccode.=" e_${elementname}_${attributename} e=myenumeration->_value;\n"; } else { $Ccode.="char*\n".&buildsymbolname($_,"tostring")."_impl (p_admsttransform myadmsttransform,e_${elementname}_${attributename} e)\n"; $Ccode.="{\n"; } foreach $v (sort @$evalue) { my$v_lc=lc $v; $Ccode.=" if(e==".buildenumerationname($elementname,$attributename,$v).")\n"; $Ccode.=" return \"${v}\";\n"; } $Ccode.=" adms_message_fatal_continue((\"select='${elementname}/${attributename}': possible values:\\n\"))\n"; $Ccode.=" adms_message_fatal_continue((\"" . join("|",sort @$evalue) ."\\n\"))\n"; $Ccode.=" adms_message_fatal((\"see %s\\n\",adms_admsttransform_uid(myadmsttransform)))\n"; $Ccode.=" return NULL;\n"; $Ccode.="}\n"; $Ccode.="\n"; if(${attributedatatypefamily} eq "reference") { $Hcode.="win32_interface char* ".&buildsymbolname($_,"tostring")."_impl (p_admsttransform myadmsttransform,p_enumeration myenumeration);\n"; } else { $Hcode.="win32_interface char* ".&buildsymbolname($_,"tostring")."_impl (p_admsttransform myadmsttransform,e_${elementname}_${attributename} e);\n"; } $Hcode.="win32_interface e_${elementname}_${attributename} ".&buildsymbolname($_,"fromstring")."_impl (p_admsttransform myadmsttransform,char*token);\n"; } } return $Hcode if($type eq "h"); return $Ccode if($type eq "c"); } sub mkAttributeValueto_cb { my$codename=shift; my$attribute=shift; my$elementname=shift; my$attributedatatypefamily=&attribute_datatypefamily($attribute); my$attributename=&attribute_name($attribute); my$attributedatatypename=&attribute_datatypename($attribute); my$attributedatatypenameImpl=&attribute_datatypenameImpl($attribute); my$code=$templates->{$codename}; die $codename if not $code; $code=~s/ELTNAME/$elementname/g; $code=~s/ATTRNAME/${attributename}/g; $code=~s/ATTRVAL/${attributedatatypename}/g; $code=~s/ATTRCONTAINER/${attributedatatypenameImpl}/g; $code=~s/ATTRID_H/$NEW{${attributedatatypename}}{Hdec}/g; $code=~s/ATTRID_C/$NEW{${attributedatatypename}}{Cdec}/g; $code=~s/^\n//; my$c=$code; $c=~s/\n?\s*H.*(\n|$)//g; my$h=$code; $h=~s/\n?\s*C.*(\n|$)//g; $c=~s/(\n?)\s*C /$1/g; $h=~s/(\n?)\s*H /$1/g; return("$h\n",$c); } sub mkAttributeValueto () { my$element=shift; my$type=shift; my$elementname=$element->getAttribute("name"); my$Hcode; my$Ccode; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributesize=&attribute_size($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); my$attributedatatypenameImpl=&attribute_datatypenameImpl($_); my$attrOnduplicate=&attrOnduplicate($_); my$attributeonrewrite=&attribute_onrewrite($_); my$containerTypeImpl=&containerTypeImpl($_); my$valueto=&buildsymbolname($_,"valueto"); my$valueof=&buildsymbolname($_,"valueof"); my$modifier=""; if((${attributesize} ne "list")&&(${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) {$modifier="const ";} $Hcode.="win32_interface inline void ${valueto} (p_$elementname my$elementname,$modifier${containerTypeImpl} _${attributename});\n"; $Ccode.="\ninline void\n${valueto} (p_$elementname my$elementname,$modifier$containerTypeImpl _${attributename})\n{\n"; if((${attributesize} ne "list")&&(${attributedatatypefamily} eq "reference")) {} if((${attributesize} ne "list")&&(${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) { $Ccode.=" if(my$elementname->_${attributename}_isdefault!=-1)\n"; $Ccode.=" free(my$elementname->_${attributename});\n"; $Ccode.=" my$elementname->_${attributename}=adms_constclone(_${attributename});\n"; $Ccode.=" my$elementname->_${attributename}_isdefault=0;\n"; } elsif((${attributesize} ne "list")&&(${attributedatatypefamily} eq "reference")&&(${attributedatatypename} eq "quark")) { $Ccode.=" if(my$elementname->_${attributename}_isdefault!=-1)\n"; $Ccode.=" adms_${attributedatatypename}_free(my$elementname->_${attributename});\n"; $Ccode.=" my$elementname->_${attributename}=_${attributename};\n"; $Ccode.=" my$elementname->_${attributename}_isdefault=0;\n"; } else { $Ccode.=" my$elementname->_${attributename}=_${attributename};\n"; $Ccode.=" my$elementname->_${attributename}_isdefault=0;\n"; } $Ccode.="}\n"; if(${attributesize} eq "list") { my($h,$c); if(($attrOnduplicate eq "")||(${attributedatatypename} eq "*")) { ($h,$c)=&mkAttributeValueto_cb("reference_prepend_once_or_passthrough",$_,$elementname); } elsif(${attributedatatypefamily} eq "reference") { my$attributeelement=$myElementHash->{${attributedatatypename}}; my@codeItem; foreach(&element_attribute($attributeelement)) { if(&isuid($_)) { my$valueof=&buildsymbolname($_,"valueof"); my$cur="${valueof}(ref${attributedatatypename})"; my$ref="my".&attribute_name($_); if((&attribute_datatypefamily($_) eq "basictype")&&(&attribute_datatypename($_) eq "base:character:array")) {push @codeItem,"!strcmp($cur,$ref)";} elsif((&attribute_datatypefamily($_) eq "reference")&&(&attribute_datatypename($_) eq "quark")) {push @codeItem,"!strcmp($cur->_value,$ref->_value)";} else {push @codeItem,"($cur==$ref)";} } } my$cmp=join "&&\nC ",@codeItem; my$reference_lookup_by_id=qq# H win32_interface ${attributedatatypenameImpl} adms_${elementname}_list_${attributename}_lookup_by_id (p_${elementname} mymy$elementname,$NEW{${attributedatatypename}}{Hdec}); C ${attributedatatypenameImpl} C adms_${elementname}_list_${attributename}_lookup_by_id (p_$elementname mymy$elementname,$NEW{${attributedatatypename}}{Hdec}) C { C p_slist list=adms_${elementname}_valueof_${attributename}(mymy$elementname); C while(list) { C p_${attributedatatypename} ref${attributedatatypename}=adms_${attributedatatypename}(list->data); C if($cmp) C return ref${attributedatatypename}; C list=list->next; C } C return NULL; C } C #; $reference_lookup_by_id=~s/^\n//; my$C=$reference_lookup_by_id; $C=~s/\n?\s*H.*(\n|$)//g; my$H=$reference_lookup_by_id; $H=~s/\n?\s*C.*(\n|$)//g; $C=~s/(\n?)\s*C /$1/g; $H=~s/(\n?)\s*H /$1/g; $c.=$C; $h.=$H."\n"; ($H,$C)=&mkAttributeValueto_cb("reference_prepend_by_id",$_,$elementname); $c.=$C; $h.=$H; while($attrOnduplicate =~ s/(\w+)//) { my($H,$C)=&mkAttributeValueto_cb("reference_prepend_by_id_once_or_$1",$_,$elementname); $c.=$C; $h.=$H; ($H,$C)=&mkAttributeValueto_cb("reference_prepend_once_or_$1",$_,$elementname); $c.=$C; $h.=$H; } } elsif(${attributedatatypefamily} eq "basictype") { my($H,$C)=&mkAttributeValueto_cb("basictype_prepend_by_id",$_,$elementname); $c.=$C; $h.=$H; while($attrOnduplicate =~ s/(\w+)//) { my($H,$C)=&mkAttributeValueto_cb("basictype_prepend_once_or_$1",$_,$elementname); $c.=$C; $h.=$H; } } else {die;} $Hcode.=$h; $Ccode.=$c; } } return $Hcode if($type eq "h"); return $Ccode if($type eq "c"); } sub mkElementCmp () { my$element=$_; my$elementname=$element->getAttribute("name"); my$code; my$codeItem; $code.="int adms_${elementname}_cmp (p_$elementname my$elementname,p_$elementname ref$elementname)\n"; $code.="{\n"; $code.=" int status;\n"; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributesize=&attribute_size($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); my$isuid=&isuid($_); if($isuid) { my$valueof=&buildsymbolname($_,"valueof"); my$cur="${valueof} (my$elementname)"; my$ref="${valueof} (ref$elementname)"; if((${attributedatatypefamily} eq "basictype")&&(${attributedatatypename} eq "base:character:array")) {push @$codeItem,"!!strcmp($cur,$ref)";} elsif((${attributedatatypefamily} eq "reference")&&(${attributedatatypename} eq "quark")) {push @$codeItem,"!!strcmp($cur->_value,$ref->_value)";} else {push @$codeItem,"($cur != $ref)";} } } $code.=" status =\n"; $code.=" (\n "; $code.=join "\n ||\n ",@$codeItem if $codeItem; $code.="\n );\n"; $code.=" return status;\n"; $code.="}\n"; $code="" if !$codeItem; return $code; } sub mkElementNew () { my$element=$_; my$elementname=$element->getAttribute("name"); my$code; my$codeItem; my@uidattributes; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributesize=&attribute_size($_); my$attributedatatypename=&attribute_datatypename($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$isuid=&isuid($_); my$attributedefault=&attribute_default($_); my$valueto=&buildsymbolname($_,"valueto"); if($isuid) { push @$codeItem,"mynew$elementname->_${attributename}_isdefault=-1;"; push @$codeItem,"$valueto (mynew$elementname,my$attributename);"; push @uidattributes,$_; push @$codeItem,"mynew$elementname->_${attributename}_isdefault=1;"; } elsif(defined ${attributedefault}) { my $defval; push @$codeItem,"mynew$elementname->_${attributename}_isdefault=-1;"; if(${attributedatatypename} eq "base:enumeration") { $defval="mynew$elementname->_${attributename}=adms_${elementname}_enumeration_${attributename}_${attributedefault};"; } elsif(${attributedatatypename} eq "base:integer") { $defval="mynew$elementname->_${attributename}=${attributedefault};" } elsif(${attributedatatypename} eq "base:real") { $defval="mynew$elementname->_${attributename}=${attributedefault};" } elsif(${attributedatatypename} eq "base:character:array") { $defval="mynew$elementname->_${attributename}=adms_constclone(\"${attributedefault}\");"; } elsif(${attributedatatypename} eq "quark") { $defval.="adms_${elementname}_valueto_${attributename}(mynew$elementname,adms_quark_new(\"${attributedefault}\"));"; } elsif(${attributedatatypename} eq "integer") { $defval.="adms_${elementname}_valueto_${attributename}(mynew$elementname,adms_integer_new(${attributedefault}));"; } elsif(${attributedatatypename} eq "real") { $defval.="adms_${elementname}_valueto_${attributename}(mynew$elementname,adms_real_new(${attributedefault}));"; } elsif(${attributedatatypename} eq "enumeration") { $defval.="adms_${elementname}_valueto_${attributename}(mynew$elementname,adms_enumeration_new(adms_${elementname}_enumeration_${attributename}_${attributedefault},".&buildsymbolname($_,"fromstring")."_impl,".&buildsymbolname($_,"tostring")."_impl));"; } push @$codeItem,$defval; push @$codeItem,"mynew$elementname->_${attributename}_isdefault=1;"; } else { push @$codeItem,"mynew$elementname->_${attributename}_isdefault=-1;"; } } $code.=$NEW{$elementname}{dec}."\n"; $code.="{\n"; $code.=" p_$elementname mynew$elementname=(p_$elementname) calloc(1,(size_t)sizeof(t_$elementname));\n"; if($elementname ne "admsmain") { $code.=" adms_global_increment_nb${elementname}new();\n"; } my$parent=&element_parent($element); if($parent) { $code.=&parent_new($element,"mynew$elementname->",$element,$parent); } $code.=" "; $code.=join "\n ",@$codeItem if $codeItem; $code.="\n"; $code.=" return mynew$elementname;\n"; $code.="}\n"; $code.=$NEWimpl{$elementname}{C}; my$count=1; my$format=$element->findnodes("uid")->get_node(0)->getAttribute ("format"); $code.="/*$format*/\n"; foreach(@uidattributes) { my$item; my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedatatypename=&attribute_datatypename($_); if($format =~ m/\$$count/) { if(${attributedatatypename} eq "base:character:array") {$item="strdup(mynew$elementname->_$attributename)";} elsif(${attributedatatypename} eq "base:enumeration") {$item="adms_constclone(adms_${elementname}_tostring_${attributename}_impl(NULL,mynew$elementname->_$attributename))";} elsif(${attributedatatypename} eq "base:integer") {$item="adms_integertostring(mynew$elementname->_$attributename)";} elsif(${attributedatatypename} eq "base:real") {$item="adms_doubletostring(mynew$elementname->_$attributename)";} elsif(${attributedatatypename} eq "*") {$item="adms_admsxml_uid(mynew$elementname->_$attributename)";} elsif(${attributedatatypename} eq "enumeration") {$item="adms_constclone(adms_${elementname}_tostring_${attributename}_impl(NULL,mynew$elementname->_$attributename))";} elsif(${attributedatatypefamily} eq "reference") {$item="adms_${attributedatatypename}_uid(mynew$elementname->_$attributename)";} else{die "attribute_datatypefamily=${attributedatatypefamily} attributedatatypename=${attributedatatypename}";} $format =~ s/\$$count/"\@$item\@"/g; } $count++; } $format="\"$format\"\@"; $format=~s/""\@//g; my@strsplit=split"\@",$format; $code.="char*adms_${elementname}_uid (p_$elementname mynew$elementname)\n"; $code.="{\n"; $code.=" char*myuid=NULL;\n"; die if not scalar(@strsplit); $count=0; foreach(@strsplit) { if(/^adms_/) { $code.=" char*myuid$count=$_;\n"; $count++; } } $count=0; foreach(@strsplit) { if(/^adms_/) { $code.=" adms_strconcat(&myuid,myuid$count);\n"; $count++; } else { $code.=" adms_strconcat2(&myuid,$_);\n"; } } $code.=" return myuid;\n"; $code.="}\n"; return $code; } sub parent_new { my$leaf=shift; my$leafpath=shift; my$element=shift; my$parent=shift; my$code; my$parentName=$parent->getAttribute("name"); my$superElement=$myElementHash->{$parentName}; my$supersuperElement=&element_parent($superElement); if($supersuperElement) { my$newcode=&parent_new(${leaf},"${leafpath}_$parentName.",$superElement,$supersuperElement); $code.=$newcode; } my@superElementAttribute=&element_attribute($superElement); foreach(@superElementAttribute) { my$attributename=&attribute_name($_); my$attributedatatypename=&attribute_datatypename($_); my$attributedatatypefamily=&attribute_datatypefamily($_); my$attributedefault=&attribute_default($_); if(${attributedefault}) { my $defval; if(${attributedefault}=~/^@/) { ${attributedefault}=~s/@//; $defval=" ${leafpath}_$parentName._${attributename}=adms_adms_enumeration_datatypename_".${leaf}->getAttribute(${attributedefault}).";\n"; } else { if(${attributedatatypefamily} eq "basictype") { if(${attributedatatypename} eq "base:integer") { $defval=" ${leafpath}_$parentName._${attributename}=${attributedefault};\n"; } elsif(${attributedatatypename} eq "base:enumeration") { $defval=" ${leafpath}_$parentName._${attributename}=adms_${parentName}_enumeration_${attributename}_${attributedefault};\n"; } } else { if(${attributedatatypename} eq "real") { $defval.=" (${leafpath}_$parentName)._${attributename}=adms_real_new(${attributedefault});\n"; } elsif(${attributedatatypename} eq "enumeration") { $defval.=" (${leafpath}_$parentName)._${attributename}="; $defval.="adms_enumeration_new(adms_${parentName}_enumeration_${attributename}_${attributedefault},".&buildsymbolname($_,"fromstring")."_impl,".&buildsymbolname($_,"tostring")."_impl);\n"; } } $defval="${leafpath}_$parentName._${attributename}=\"${attributedefault}\"" if((${attributedatatypename} eq "quark")&&((${attributedefault} ne "myfile"))); $defval="${leafpath}_$parentName._${attributename}=${attributedefault}" if((${attributedatatypename} eq "quark")&&((${attributedefault} eq "myfile"))); } $code.=$defval; } } return $code; } sub miscellaneous_code { my$codeH; my$codeC; $codeC.="\n/*-- Miscellaneous routines --*/\n"; $codeC.=q@ char*adms_integertostring(int value) { char*string=malloc(sizeof(char)*50); sprintf(string,"%i",value); return string; } char*adms_doubletostring(double value) { if(isnan(value)) { char*string=malloc(sizeof(char)*4); sprintf(string,"nan"); return string; } else { char*string=malloc(sizeof(char)*50); sprintf(string,"%e",value); return string; } } int adms_file_isregular(const char* myfilename) { return((access(myfilename,ADMS_F_OK)==0)); } int adms_file_isdirectory(const char* myfilename) { struct stat s; return((stat(myfilename,&s)==0)&&(s.st_mode&ADMS_S_IFDIR)); } int adms_setenv(const char*myname,const char*myvalue) { int myres; #if defined(HAVE_PUTENV) char*myassign=NULL; adms_strconcat2(&myassign,myname); adms_strconcat2(&myassign,"="); adms_strconcat2(&myassign,myvalue); myres=putenv(myassign); free(myassign); #else myres=setenv(myname,myvalue,1); #endif return (myres==0); } /*i*/p_slist adms_slist_last (p_slist l) { if(l) { while(l->next) l=l->next; } return l; } /*i*/p_slist adms_slist_new (p_adms d) { p_slist newl=NULL; adms_slist_push(&newl,d); return newl; } /*i*/p_slist adms_slist_copy (p_slist l) { p_slist copiedl=NULL; while(l) { adms_slist_push(&copiedl,l->data); l=l->next; } return adms_slist_reverse(copiedl); } /*i*/void adms_slist_push(p_slist* l,p_adms data) { p_slist n=malloc(sizeof(t_slist)); n->next=*l; n->data=data; *l=n; } /*i*/p_adms adms_slist_pull(p_slist* l) { if(*l) { p_slist n=*l; p_adms data=n->data; *l=(*l)->next; free(n); return data; } return NULL; } /*i*/void adms_slist_concat (p_slist* l1,p_slist l2) { if(l2) { if(*l1) adms_slist_last(*l1)->next=l2; else *l1=l2; } } /*i*/unsigned int adms_slist_length (p_slist l) { unsigned int length=0; while(l) { length++; l=l->next; } return length; } /*i*/p_slist adms_slist_nth (p_slist l,unsigned int n) { while (n-->0 && l) l=l->next; return l; } /*i*/p_adms adms_slist_nth_data (p_slist l,unsigned int n) { while (n-->0 && l) l=l->next; return l ? l->data : ((p_adms)0); } /*i*/p_slist adms_slist_find (p_slist l,const p_adms data) { while(l) { if(l->data==data) break; l=l->next; } return l; } /*i*/int adms_slist_index (p_slist l, const p_adms data) { int i=0; while(l) { if(l->data==data) return i; i++; l=l->next; } return -1; } /*i*/p_slist adms_slist_reverse (p_slist l) { p_slist p=NULL; while(l) { p_slist n=l->next; l->next=p; p=l; l=n; } return p; } /*i*/void adms_slist_free (p_slist l) { while(l) { p_slist freed=l; l=l->next; free(freed); } } @; foreach(@$myElementArray) { my$elementname=$_->getAttribute("name"); $codeC.="int globalnb${elementname}new=0, globalnb${elementname}destroy=0;\n"; $codeC.="inline int adms_global_nb${elementname}new(void) {return globalnb${elementname}new;};\n"; $codeC.="inline int adms_global_nb${elementname}destroy(void) {return globalnb${elementname}destroy;};\n"; $codeC.="inline void adms_global_increment_nb${elementname}new(void) {globalnb${elementname}new++;};\n"; $codeC.="inline void adms_global_increment_nb${elementname}destroy(void) {globalnb${elementname}destroy++;};\n"; $codeH.="win32_interface inline int adms_global_nb${elementname}new(void);\n"; $codeH.="win32_interface inline int adms_global_nb${elementname}destroy(void);\n"; $codeH.="win32_interface inline void adms_global_increment_nb${elementname}new(void);\n"; $codeH.="win32_interface inline void adms_global_increment_nb${elementname}destroy(void);\n"; } $codeC.="p_admsmain globaladmsmain;\n"; $codeC.="p_admsmain adms_global_admsmain(void) {return globaladmsmain;}\n"; $codeC.="void adms_global_valueto_admsmain(p_admsmain myglobaladmsmain) {globaladmsmain=myglobaladmsmain;}\n"; $codeC.="\n/*-- Messaging --*/\n"; $codeC.="\n"; sub message { my($name,$ofh,$isfatal)=(shift,shift,shift); my$codeC; my$prefix=sprintf("\"[%-7s]",$name); $prefix=~s/ /\./g; $prefix.=" \""; $codeC.="_t_message (adms_message_${name}_impl) { va_list ap; int insideformat=0; int i; char* s; double d; void* p; fputs($prefix,$ofh); va_start(ap, format); while(*format) { switch(*format) { case '%': insideformat=insideformat?0:1; break; default: { if(insideformat) { insideformat=0; switch(*format) { case 's': s=va_arg (ap,char*); fputs(s,$ofh); break; case 'e': d=va_arg (ap,double); printf(\"%e\",d); break; case 'g': d=va_arg (ap,double); printf(\"%g\",d); break; case 'f': d=va_arg (ap,double); printf(\"%f\",d); break; case 'i': i=va_arg (ap,int); printf(\"%i\",i); break; case 'p': p=va_arg (ap,void*); printf(\"%p\",p); break; default: fputc(*format,$ofh); } } else fputc(*format,$ofh); } } format++; } va_end (ap); fflush($ofh); "; if($isfatal) { $codeC.=" if(getenv(\"adms_breakpoint\"))\n"; $codeC.=" G_BREAKPOINT();\n"; $codeC.=" else\n"; $codeC.=" exit(1);\n"; } $codeC.="}\n"; $codeC.="_t_message (adms_message_${name}_continue_impl) { va_list ap; int insideformat=0; int i; char* s; double d; void* p; "; if($isfatal) { $codeC.=" fputs($prefix,$ofh);\n"; } $codeC.=" va_start(ap, format); while(*format) { switch(*format) { case '%': insideformat=insideformat?0:1; break; default: { if(insideformat) { insideformat=0; switch(*format) { case 's': s=va_arg (ap,char*); fputs(s,$ofh); break; case 'e': d=va_arg (ap,double); printf(\"%e\",d); break; case 'g': d=va_arg (ap,double); printf(\"%g\",d); break; case 'f': d=va_arg (ap,double); printf(\"%f\",d); break; case 'i': i=va_arg (ap,int); printf(\"%i\",i); break; case 'p': p=va_arg (ap,void*); printf(\"%p\",p); break; default: fputc(*format,$ofh); } } else fputc(*format,$ofh); } } format++; } va_end (ap); fflush($ofh); }\n"; return $codeC; } $codeH.="\n/*-- Miscellaneous routines --*/\n"; $codeH.=q@ typedef struct s_slist t_slist; typedef t_slist* p_slist; /*d*/win32_interface char*adms_integertostring(int value); /*d*/win32_interface char*adms_doubletostring(double value); /*d*/win32_interface int adms_setenv(const char*myname,const char*myvalue); /*d*/win32_interface int adms_file_isregular(const char* myfilename); /*d*/win32_interface int adms_file_isdirectory(const char* myfilename); #define adms_slist(item) ((p_slist)(item)) /*d*/win32_interface p_slist adms_slist_new (p_adms d); /*d*/win32_interface p_slist adms_slist_copy (p_slist l); /*d*/win32_interface void adms_slist_concat (p_slist* l1,p_slist l2); /*d*/win32_interface p_slist adms_slist_find (p_slist l,const p_adms data); /*d*/win32_interface void adms_slist_free (p_slist l); /*d*/win32_interface int adms_slist_index (p_slist l, const p_adms data); /*d*/win32_interface p_slist adms_slist_last (p_slist l); /*d*/win32_interface unsigned int adms_slist_length (p_slist l); /*d*/win32_interface p_slist adms_slist_nth (p_slist l,unsigned int n); /*d*/win32_interface p_adms adms_slist_nth_data (p_slist l,unsigned int n); /*d*/win32_interface void adms_slist_print(const char* message,p_slist l); /*d*/win32_interface p_adms adms_slist_pull(p_slist* l); /*d*/win32_interface void adms_slist_push(p_slist* l,p_adms data); /*d*/win32_interface p_slist adms_slist_reverse (p_slist l); struct s_slist { p_adms data; p_slist next; }; @; $codeH.="\n"; $codeH.="#define ENUMERATION(v,e,a) adms_enumeration_new(v,adms_##e##_fromstring_##a##_impl,adms_##e##_tostring_##a##_impl)\n"; $codeH.="\n"; $codeH.="typedef void *(*p_anyfunction) (void *arg);\n"; $codeH.="typedef int (*p_getinteger) (void* name);\n"; $codeH.="typedef char* (*p_valuetostring) (p_admsttransform myadmsttransform, void* name);\n"; $codeH.="typedef int (*p_valuefromstring) (p_admsttransform myadmsttransform, void* name);\n"; $codeH.="typedef p_real (*p_getreal) (void* name);\n"; $codeH.="typedef char * (*p_getstring) (void* name);\n"; $codeH.="typedef p_slist(*p_getlist) (p_adms name);\n"; $codeH.="typedef void (*p_admsvalueto) (p_adms myadms,p_adms myvalue);\n"; $codeH.="typedef void *(*p_dmsvalueof) (p_adms myadms);\n"; $codeH.="\n"; $codeH.="win32_interface p_admsmain adms_global_admsmain(void);\n"; $codeH.="win32_interface void adms_global_valueto_admsmain(p_admsmain myglobaladmsmain);\n"; $codeH.="\n"; $codeH.="typedef p_adms (t_new) (p_adms arguments[]);\n"; $codeH.="typedef p_adms (*p_new) (p_adms arguments[]);\n"; $codeH.="#define _t_new(function) p_adms (function) (p_adms arguments[])\n"; $codeH.="\n"; $codeH.="typedef const char* (t_returnstring) (void);\n"; $codeH.="typedef const char* (*p_returnstring) (void);\n"; $codeH.="#define _t_returnstring(function) const char* (function) (void)\n"; $codeH.="\n"; $codeH.="typedef int (t_cmp) (p_adms myadms, p_adms myadmsref);\n"; $codeH.="typedef int (*p_cmp) (p_adms myadms, p_adms myadmsref);\n"; $codeH.="#define _t_cmp(function) int (function) (p_adms myadms, p_adms myadmsref)\n"; $codeH.="\n/*-- Messaging --*/\n"; $codeH.="\n"; $codeH.="typedef void (t_message) (const char*format, ...);\n"; $codeH.="typedef void (*p_message) (const char*format, ...);\n"; $codeH.="#define _t_message(function) void (function) (const char*format, ...)\n"; my@message=( ["info","stdout",0], ["usage","stdout",0], ["verbose","stdout",0], ["debug","stdout",0], ["dbg_vla","stdout",0], ["dbg_xml","stdout",0], ["dbg_mem","stdout",0], ["hint","stderr",0], ["warning","stderr",0], ["obsolete","stderr",0], ["error","stderr",0], ["fatal","stderr",1] ); $codeH.=q[ win32_interface inline char*adms_consttoupper(const char*m); win32_interface inline char*adms_consttolower(const char*m); win32_interface inline char*adms_constclone(const char*m); win32_interface inline char*adms_constnclone(const char*m,const int l); win32_interface inline char*adms_m2nclone(const char*m,const char*n); win32_interface inline void adms_strconcat(char **s1,char *s2); win32_interface inline void adms_strconcat2(char **s1,const char *s2); ]; $codeC.=q[ inline char*adms_consttoupper(const char*m) { int l=strlen(m); char*mycpy=(char*)malloc((l+1)*sizeof(char)); mycpy[l--]='\0'; for(;l>=0;l--) mycpy[l]=toupper(m[l]); return mycpy; } inline char*adms_consttolower(const char*m) { int l=strlen(m); char*mycpy=(char*)malloc((l+1)*sizeof(char)); mycpy[l--]='\0'; for(;l>=0;l--) mycpy[l]=tolower(m[l]); return mycpy; } inline char*adms_constclone(const char*m) { int l=strlen(m); char*mycpy=(char*)malloc((l+1)*sizeof(char)); memcpy(mycpy,m,l); mycpy[l]='\0'; return mycpy; } inline char*adms_constnclone(const char*m,const int l) { char*mycpy=(char*)malloc((l+1)*sizeof(char)); memcpy(mycpy,m,l); mycpy[l]='\0'; return mycpy; } /*clone array (m,n(: "abcdefghijkl\0" returns as "cdef\0"*/ /* m n */ /* same as adms_constnclone(m,n-m) */ inline char*adms_m2nclone(const char*m,const char*n) { int l=(char*)n-(char*)m; char*mycpy=(char*)malloc((l+1)*sizeof(char)); memcpy(mycpy,m,l); mycpy[l]='\0'; return mycpy; } /*s1: realloced s2: constant ret: s1=s1s2*/ inline void adms_strconcat2(char **s1,const char *s2) { if(*s1) { int l1=strlen(*s1); int l2=strlen(s2); *s1=(char*)realloc(*s1,(l1+l2+1)*sizeof(char)); memcpy(*s1+l1,s2,l2+1); } else *s1=strdup(s2); } /*s1: realloced s2: freed ret: s1=s1s2*/ inline void adms_strconcat(char **s1,char *s2) { adms_strconcat2(s1,s2); free(s2); } ]; $codeC.="\n"; foreach my$mess(@message) { my$name=$mess->[0]; my$outputfile=$mess->[1]; my$isfatal=$mess->[2]; $codeC.=message($name,$outputfile,$isfatal); $codeH.="win32_interface t_message adms_message_${name}_impl;\n"; $codeH.="win32_interface t_message adms_message_${name}_continue_impl;\n"; $codeH.="#define adms_message_${name}(VAARGS)\\\n"; $codeH.="{\\\n"; $codeH.=" if((adms_global_admsmain())\\\n"; $codeH.=" &&(adms_admsmain_valueof_${name} (adms_global_admsmain())->_value==adms_admsmain_enumeration_${name}_yes))\\\n"; $codeH.=" adms_message_${name}_impl VAARGS;\\\n"; $codeH.="}\n"; $codeH.="#define adms_message_${name}_continue(VAARGS)\\\n"; $codeH.="{\\\n"; $codeH.=" if((adms_global_admsmain())\\\n"; $codeH.=" &&(adms_admsmain_valueof_${name} (adms_global_admsmain())->_value==adms_admsmain_enumeration_${name}_yes))\\\n"; $codeH.=" adms_message_${name}_continue_impl VAARGS;\\\n"; $codeH.="}\n"; } $codeH.="\n"; return ($codeH,$codeC); } sub build_admsxml_allattribute { my $codeC; foreach(@$myElementArray) { my$element=$_; my$elementname=$element->getAttribute("name"); my@attribute=&element_attribute($element); my$value=""; my$size=1; foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypefamily=&attribute_datatypefamily($_); if(${attributedatatypefamily} eq "reference") { $value.="\"${attributename}\","; $size++; } } $codeC.="const char*adms_element_${elementname}_allattribute[$size]={${value}NULL};\n"; } return $codeC; } sub build_admsxml_accessors { my$codeH; my$codeC; $codeC.="/*-- accessors: grap data from adms.xml based on adms element name and attribute name --*/\n"; $codeC.="#include \n"; $codeC.="\n"; #accessors: size valueof valueto #methods: isdefault uid new cmp allattribute foreach my$accessor qw(size valueof valueto isdefault uid new cmp allattribute) { my$input; my$output; my$datatypename; if($accessor eq "uid") {$input="p_adms myitem";$output="char*";$datatypename=" int dataTypeName=myitem->_datatypename;\n";} elsif($accessor eq "new") {$input="p_admsttransform myadmsttransform";$output="p_new";$datatypename=" char*dataTypeName=myadmsttransform->_zzdatatype?myadmsttransform->_zzdatatype->_value:\"unknown\";\n";} elsif($accessor eq "cmp") {$input="p_admst myadmst";$output="p_cmp";$datatypename=" int dataTypeName=myadmst->_item->_datatypename;\n";} elsif($accessor eq "allattribute") {$input="p_admst myadmst";$output="const char**";$datatypename=" int dataTypeName=myadmst->_item->_datatypename;\n";} elsif($accessor eq "valueof") {$input="const p_admst myadmst,const char*myattributename";$output="p_adms";} elsif($accessor eq "valueto") {$input="const p_admst myadmst,const char*myattributename";$output="p_admsvalueto";} elsif($accessor eq "size") {$input="p_admsttransform myadmsttransform, const p_admst myadmst,const char*myattributename";$output="int";} else {$input="const p_admst myadmst,const char*myattributename";$output="int";} $codeH.="win32_interface $output adms_admsxml_$accessor ($input);\n"; $codeC.="$output adms_admsxml_$accessor ($input)\n"; $codeC.="{\n"; if(not defined $datatypename) { $datatypename.=" e_adms_datatypename myelementname;\n"; $datatypename.=" if(!strcmp(myadmst->_attributename,\"adms\"))\n"; $datatypename.=" myelementname=adms_adms_enumeration_datatypename_adms;\n"; $datatypename.=" else if(!strcmp(myadmst->_attributename,\"math\"))\n"; $datatypename.=" myelementname=adms_adms_enumeration_datatypename_math;\n"; $datatypename.=" else if(!strcmp(myadmst->_attributename,\"subexpression\"))\n"; $datatypename.=" myelementname=adms_adms_enumeration_datatypename_subexpression;\n"; $datatypename.=" else\n"; $datatypename.=" myelementname=myadmst->_item->_datatypename;\n"; $datatypename.=" /*alias*/\n"; $datatypename.=" if(myadmst->_item\n"; $datatypename.=" &&(!strcmp(myattributename,\"static\")||!strcmp(myattributename,\"dynamic\"))\n"; $datatypename.=" )\n"; $datatypename.=" {\n"; $datatypename.=" if(0\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_block\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_blockvariable\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_nilled\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_expression\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_assignment\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_contribution\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_conditional\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_variable\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_callfunction\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_case\n"; $datatypename.=" ||myelementname==adms_adms_enumeration_datatypename_whileloop\n"; $datatypename.=" )\n"; $datatypename.=" myelementname=adms_adms_enumeration_datatypename_math;\n"; $datatypename.=" }\n"; } $codeC.=$datatypename; foreach(@$myElementArray) { my$elementname=$_->getAttribute("name"); next if $elementname eq "adms"; if($accessor eq "uid") { $codeC.=" if(dataTypeName==adms_adms_enumeration_datatypename_$elementname)\n"; $codeC.=" return adms_${elementname}_$accessor(adms_$elementname(myitem));\n"; } elsif($accessor eq "new") { $codeC.=" if(!strcmp(dataTypeName,\"$elementname\"))\n"; $codeC.=" return (p_new) adms_${elementname}_${accessor}_impl;\n"; } elsif($accessor eq "cmp") { $codeC.=" if(dataTypeName==adms_adms_enumeration_datatypename_$elementname)\n"; $codeC.=" return ($output)adms_${elementname}_$accessor;\n"; } elsif($accessor eq "allattribute") { $codeC.=" if(dataTypeName==adms_adms_enumeration_datatypename_$elementname)\n"; $codeC.=" return adms_element_${elementname}_$accessor;\n"; } } foreach(@$myElementArray) { next if $accessor =~ "uid\|new\|cmp\|allattribute"; my$element=$_; my$elementname=$element->getAttribute("name"); $codeC.=" if(myelementname==adms_adms_enumeration_datatypename_$elementname)\n {\n"; my@attribute=&element_attribute($element); foreach(@attribute) { my$attributename=&attribute_name($_); my$attributedatatypename=&attribute_datatypename($_); my$attributedatatypefamily=&attribute_datatypefamily($_); $codeC.=" if(!strcmp(myattributename,\"$attributename\"))\n"; if($attributedatatypefamily eq "basictype") { if($input=~/myadmst,.*myattributename/) { $codeC.=" {\n"; $codeC.=" adms_message_fatal_continue((\"access to basic type '$attributedatatypename' not allowed in $accessor(%s/%s)\\n\",myadmst->_attributename,myattributename))\n"; $codeC.=" adms_message_fatal((\"see %s\\n\",adms_admst_uid(myadmst)))\n"; $codeC.=" }\n"; } else { die; } } elsif($accessor eq "size") {$codeC.=" return adms_admst_enumeration_${accessor}_".&attribute_size($_).";\n";} elsif($accessor eq "valueto") {$codeC.=" return ($output)".&buildsymbolname($_,$accessor).";\n";} elsif($accessor eq "valueof") {$codeC.=" return ($output)".&buildsymbolname($_,$accessor)."(myadmst->_item);\n";} elsif($accessor eq "isdefault") {$codeC.=" return ($output)".&buildsymbolname($_,$accessor)."(myadmst->_item);\n";} else { my$val="adms_adms_enumeration_${accessor}_".&{"attribute_$accessor"}($_); $val=~s/\*/_star/; $codeC.=" return ".$val.";\n"; } } my$parent=$element; while($parent=&element_parent($parent)) { my$attributename=$parent->getAttribute ("name"); if($accessor eq "size") { $codeC.=" if(!strcmp(myattributename,\"${attributename}\"))\n"; $codeC.=" return adms_admst_enumeration_${accessor}_scalar;\n"; } elsif($accessor eq "valueof") { $codeC.=" if(!strcmp(myattributename,\"${attributename}\"))\n"; $codeC.=" return ($output)".&buildsupersymbolname($element,$parent,$accessor)."(myadmst->_item);\n"; } elsif($accessor eq "valueto") {} elsif($accessor eq "isdefault") {} } $codeC.=" }\n"; } if($accessor eq "size") { $codeC.=" {\n"; $codeC.=" p_adms myitem=myadmst->_item;\n"; $codeC.=" char*myelementname=myitem?adms_adms_tostring_datatypename_impl(myadmsttransform,myitem->_datatypename):myadmst->_attributename;\n"; $codeC.=" adms_message_fatal_continue((\"missing attribute %s/%s\\n\",myelementname,myattributename))\n"; $codeC.=" adms_message_fatal_continue((\"see %s\\n\",adms_admsttransform_uid(myadmsttransform)))\n"; $codeC.=" adms_message_fatal((\"called by %s\\n\",adms_admst_uid(myadmst)))\n"; $codeC.=" }\n"; } elsif($input=~/myadmst,.*myattributename/) { $codeC.=" {\n"; $codeC.=" p_adms myitem=myadmst->_item;\n"; $codeC.=" char*myelementname=myitem?adms_adms_tostring_datatypename_impl(myadmst->_admsttransform,myitem->_datatypename):myadmst->_attributename;\n"; $codeC.=" adms_message_fatal_continue((\"missing attribute %s/%s\\n\",myelementname,myattributename))\n"; $codeC.=" adms_message_fatal((\"see %s\\n\",adms_admst_uid(myadmst)))\n"; $codeC.=" }\n"; } elsif($input=~/myadmsttransform/) { $codeC.=" adms_message_fatal_continue((\"%s: missing element %s\\n\",myadmsttransform->_zzdatatype->_value))\n"; $codeC.=" adms_message_fatal((\"see %s\\n\",adms_admsttransform_uid(myadmsttransform)))\n"; } else { $codeC.=" adms_message_fatal_continue((\"%s:%i: internal error - should not be reached\\n\",__FILE__,__LINE__))\n"; } if($accessor eq "size") {$codeC.=" return 0;\n";} elsif($accessor eq "isdefault") {$codeC.=" return 0;\n";} else {$codeC.=" return NULL;\n";} $codeC.="}\n"; } return ($codeH,$codeC); }