# This is the PerSAX Handlers Package package DOMTSHandler; use Switch; use XML::XPath;use XML::XPath::XMLParser; our $description = 0;our $string_index = 0;our $ret_index = 0;our $condition_index = 0;our $test_index = 0;our $iterator_index = 0;our $temp_index = 0;# Sometimes, we need temp nodesour $tnode_index = 0;our $dom_feature = "\"XML\"";our %bootstrap_api = ( dom_implementation_create_document_type => "", dom_implementation_create_document => "",);our %native_interface = ( DOMString => \&generate_domstring_interface, DOMTimeStamp => "", DOMUserData => "", DOMObject =>"",);our %special_type = ( # Some of the type are not defined now! boolean => "bool ", int => "int32_t ", "unsigned long" => "dom_ulong ", DOMString => "dom_string *", List => "list *", Collection => "list *", DOMImplementation => "dom_implementation *", NamedNodeMap => "dom_namednodemap *", NodeList => "dom_nodelist *", HTMLCollection => "dom_html_collection *", HTMLFormElement => "dom_html_form_element *", CharacterData => "dom_characterdata *", CDATASection => "dom_cdata_section *", HTMLAnchorElement => "dom_html_anchor_element *", HTMLElement => "dom_html_element *", HTMLTableCaptionElement => "dom_html_table_caption_element *", HTMLTableSectionElement => "dom_html_table_section_element *", HTMLTableElement => "dom_html_table_element *", HTMLTableRowElement => "dom_html_table_row_element *", HTMLOptionsCollection => "dom_html_options_collection *",);our %special_prefix = ( DOMString => "dom_string", DOMImplementation => "dom_implementation", NamedNodeMap => "dom_namednodemap", NodeList => "dom_nodelist", HTMLCollection => "dom_html_collection", HTMLFormElement => "dom_html_form_element", CharacterData => "dom_characterdata", CDATASection => "dom_cdata_section *", HTMLHRElement => "dom_html_hr_element", HTMLBRElement => "dom_html_br_element", HTMLLIElement => "dom_html_li_element", HTMLTableCaptionElement => "dom_html_table_caption_element", HTMLTableSectionElement => "dom_html_table_section_element", HTMLIsIndexElement => "dom_html_isindex_element", HTMLIFrameElement => "dom_html_iframe_element", HTMLOListElement => "dom_html_olist_element", HTMLDListElement => "dom_html_dlist_element", caption => "dom_html_table_caption_element *", section => "dom_html_table_section_element *", createCaption => "dom_html_element *", createTHead => "dom_html_element *", createTFoot => "dom_html_element *", deleteCaption => "dom_html_element *", deleteTHead => "dom_html_element *", deleteTFoot => "dom_html_element *", insertRow => "dom_html_element *", deleteRow => "dom_html_element *", form => "dom_html_form_element *",); our %unref_prefix = ( DOMString => "dom_string", NamedNodeMap => "dom_namednodemap", NodeList => "dom_nodelist", HTMLCollection => "dom_html_collection", HTMLOptionsCollection => "dom_html_options_collection", HTMLDocument => "dom_html_document",); our %special_method = (); our %special_attribute = ( namespaceURI => "namespace", URL => "url",); our %no_unref = ( "boolean" => 1, "int" => 1, "unsigned int" => 1, "unsigned long" => 1, "List" => 1, "Collection" => 1,); our %override_suffix = ( boolean => "bool", int => "int", "unsigned long" => "unsigned_long", DOMString => "domstring", DOMImplementation => "domimplementation", NamedNodeMap => "domnamednodemap", NodeList => "domnodelist", HTMLCollection => "domhtmlcollection", Collection => "list", List => "list",); our %exceptions = ( DOM_NO_ERR => 0, DOM_INDEX_SIZE_ERR => 1, DOM_DOMSTRING_SIZE_ERR => 2, DOM_HIERARCHY_REQUEST_ERR => 3, DOM_WRONG_DOCUMENT_ERR => 4, DOM_INVALID_CHARACTER_ERR => 5, DOM_NO_DATA_ALLOWED_ERR => 6, DOM_NO_MODIFICATION_ALLOWED_ERR => 7, DOM_NOT_FOUND_ERR => 8, DOM_NOT_SUPPORTED_ERR => 9, DOM_INUSE_ATTRIBUTE_ERR => 10, DOM_INVALID_STATE_ERR => 11, DOM_SYNTAX_ERR => 12, DOM_INVALID_MODIFICATION_ERR => 13, DOM_NAMESPACE_ERR => 14, DOM_INVALID_ACCESS_ERR => 15, DOM_VALIDATION_ERR => 16, DOM_TYPE_MISMATCH_ERR => 17, DOM_UNSPECIFIED_EVENT_TYPE_ERR => (1<<30)+0, DOM_DISPATCH_REQUEST_ERR => (1<<30)+1, DOM_NO_MEM_ERR => (1<<31)+0, ); our @condition = qw(same equals notEquals less lessOrEquals greater greaterOrEquals isNull notNull and or xor not instanceOf isTrue isFalse hasSize contentType hasFeature implementationAttribute); our @exception = qw(INDEX_SIZE_ERR DOMSTRING_SIZE_ERR HIERARCHY_REQUEST_ERR WRONG_DOCUMENT_ERR INVALID_CHARACTER_ERR NO_DATA_ALLOWED_ERR NO_MODIFICATION_ALLOWED_ERR NOT_FOUND_ERR NOT_SUPPORTED_ERR INUSE_ATTRIBUTE_ERR NAMESPACE_ERR UNSPECIFIED_EVENT_TYPE_ERR DISPATCH_REQUEST_ERR); our @assertion = qw(assertTrue assertFalse assertNull assertNotNull assertEquals assertNotEquals assertSame assertInstanceOf assertSize assertEventCount assertURIEquals); our @assertexception = qw(assertDOMException assertEventException assertImplementationException); our @control = qw(if while for-each else); our @framework_statement = qw(assign increment decrement append plus subtract mult divide load implementation comment hasFeature implementationAttribute EventMonitor.setUserObj EventMonitor.getAtEvents EventMonitor.getCaptureEvents EventMonitor.getBubbleEvents EventMonitor.getAllEvents wait); sub new { my $type = shift; my $dtd = shift; my $chdir = shift; my $dd = XML::XPath->new(filename => $dtd); my $self = { # The DTD file of the xml files dd => $dd, # To indicate whether we are in comments comment => 0, # To indicate that whether we are in <comment> element inline_comment => 0, # The stack of elements encountered utill now context => [], # The map for <var> name => type var => {}, # See the comment on generate_condition2 for this member condition_stack => [], # The list for UNREF unref => [], string_unref => [], block_unrefs => ["!!!"], # The indent of current statement indent => "", # The variables for List/Collection # We now, declare an array for a list and then add them into a list # The map for all the List/Collection in one test # "List Name" => "Member type" list_map => {}, # The name of the current List/Collection list_name => "", # The number of items of the current List/Collection list_last_name => [], # The number of items of the current List/Collection list_num => 0, # Whether List/Collection has members list_hasmem => 0, # The type of the current List/Collection member_list_declared => 0, # The type of the current List/Collection list_type => "", # Whether we are in exception assertion exception => 0, # Where to chdir chdir => $chdir }; return bless $self, $type;} sub start_element { my ($self, $element) = @_; my $en = $element->{Name}; my $dd = $self->{dd}; my $ct = $self->{context}; push(@$ct, $en); switch ($en) { case "test" { ; } case "metadata" { # start comments here print "/*\n"; $self->{comment} = 1; } # Print the var definition case "var" { $self->generate_var($element->{Attributes}); } case "member" { if ($self->{context}->[-2] eq "var") { if ($self->{"list_hasmem"} eq 1) { print ", "; } $self->{"list_hasmem"} = 1; $self->{"list_num"} ++; } } # The framework statements case [@framework_statement] { # Because the implementationAttribute & hasFeature belongs to both # framework-statement and condition, we should distinct the two # situation here. Let the generate_condtion to do the work. if ($en eq "hasFeature" || $en eq "implementationAttribute") { next; } $self->generate_framework_statement($en, $element->{Attributes}); } case [@control] { $self->generate_control_statement($en, $element->{Attributes}); } # Test condition case [@condition] { $self->generate_condition($en, $element->{Attributes}); } # The assertsions case [@assertion] { $self->generate_assertion($en, $element->{Attributes}); } case [@assertexception] { # Indeed, nothing to do here! } # Deal with exception case [@exception] { # Just see end_element $self->{'exception'} = 1; } # Then catch other case else { # we don't care the comment nodes if ($self->{comment} eq 0) { $self->generate_interface($en, $element->{Attributes}); } } }} sub end_element { my ($self, $element) = @_; my @ct = @{$self->{context}}; my $name = pop(@{$self->{context}}); switch ($name) { case "metadata" { print "*/\n"; $self->{comment} = 0; $self->generate_main(); } case "test" { $self->cleanup(); } case "var" { $self->generate_list(); } # End of condition case [@condition] { $self->complete_condition($name); } # The assertion case [@assertion] { $self->complete_assertion($name); } case [@control] { $self->complete_control_statement($name); } case [@exception] { $name = "DOM_".$name; print "assert(exp == $exceptions{$name});\n"; $self->{'exception'} = 0; } }} sub characters { my ($self, $data) = @_; our $description; my $ct = $self->{context}; if ($self->{"inline_comment"} eq 1) { print "$data->{Data}"; return ; } # We print the comments here if ($self->{comment} eq 1) { # So, we are in comments state my $top = $ct->[$#{$ct}]; if ($top eq "metadata") { return; } if ($top eq "description") { if ($description eq 0) { print "description: \n"; $description = 1; } print "$data->{Data}"; } else { print "$top: $data->{Data}\n"; } return; } if ($self->{context}->[-1] eq "member") { # We should mark that the List/Collection has members $self->{"list_hasmem"} = 1; # Here, we should detect the characters type # whether it is a integer or string (now, we only take care # of the two types, because I did not find any other type). if ($self->{"list_type"} eq "") { if ($data->{Data} =~ /^\"/) { $self->{"list_type"} = "char *"; print "const char *".$self->{"list_name"}."Array[] = \{ $data->{Data}"; } else { if ($data->{Data} =~ /^[0-9]+/) { $self->{"list_type"} = "int *"; print "int ".$self->{"list_name"}."Array[] = \{ $data->{Data}"; } else { die "Some data in the <member> we can't process: \"$data->{Data}\""; } } } else { # So, we must have known the type, just output the member print "$data->{Data}"; } }} sub generate_main { my $self = shift; # Firstly, push a new "b" to the string_unref list push(@{$self->{"string_unref"}}, "b"); print << "__EOF__" #include <stdio.h>#include <string.h>#include <stdbool.h>#include <unistd.h> #include <dom/dom.h>#include <dom/functypes.h> #include <domts.h> dom_implementation *doc_impl; int main(int argc, char **argv){ dom_exception exp; (void)argc; (void)argv; if (chdir("$self->{chdir}") < 0) { perror("chdir (\\"$self->{chdir})\\""); return 1; } int list_temp[100], count = -1;__EOF__} # Note that, we have not just declare variables here# we should also define EventListener here!# I think this should be done after the EventListener design# is completesub generate_var { my ($self, $ats) = @_; my $type = ""; my $dstring = ""; # For the case like <var name="v" type="DOMString" value="some some" if ($ats->{"type"} eq "DOMString" and exists $ats->{"value"}) { $dstring = $self->generate_domstring($ats->{"value"}); $ats->{"value"} = $dstring; } $type = type_to_ctype($ats->{"type"}); if ($type eq "") { print "Not implement this type now\n"; return; } print "\t$type$ats->{'name'}"; if (exists $ats->{"value"}) { print " = $ats->{'value'};\n"; } else { if ($type =~ m/\*/) { print " = NULL;\n"; } else { print ";\n"; } } my $var = $self->{"var"}; $var->{$ats->{"name"}} = $ats->{"type"}; # If the type is List/Collection, we should take care of it if ($ats->{"type"} =~ /^(List|Collection)$/) { $self->{"list_name"} = $ats->{"name"}; }} sub generate_list { my $self = shift; # We should deal with the end of <var> when the <var> is declaring a List/Collection if ($self->{"list_hasmem"} eq 1) { # Yes, we are in List/Collection declaration # Firstly, enclose the Array declaration print "};\n"; # Now, we should create the list * for the List/Collection # Note, we should deal with "int" or "string" type with different params. if ($self->{"list_type"} eq "char *") { print $self->{"list_name"}." = list_new(STRING);\n"; } if ($self->{"list_type"} eq "int *") { print $self->{"list_name"}." = list_new(INT);\n"; while(defined ($x = pop @{$self->{"list_last_name"}})) { print $x." = list_new(INT);\n"; } } while(defined($x = pop(@{$self->{"list_last_name"}}))) { print $x." = list_new(DOM_STRING);\n"; } $self->{"member_list_declared"} = 1; if ($self->{"list_type"} eq "") { die "A List/Collection has children member but no type is impossible!"; } if ($self->{"list_type"} eq "int *") { for (my $i = 0; $i < $self->{"list_num"}; $i++) { # Use *(char **) to convert char *[] to char * print "list_add(".$self->{"list_name"}.", (int *)(".$self->{"list_name"}."Array) + $i);\n"; }Lines 1–500 of 1700. Load more
# This is the PerSAX Handlers Package package DOMTSHandler; use Switch; use XML::XPath; use XML::XPath::XMLParser; our $description = 0; our $string_index = 0; our $ret_index = 0; our $condition_index = 0; our $test_index = 0; our $iterator_index = 0; our $temp_index = 0; # Sometimes, we need temp nodes our $tnode_index = 0; our $dom_feature = "\"XML\""; our %bootstrap_api = ( dom_implementation_create_document_type => "", dom_implementation_create_document => "", ); our %native_interface = ( DOMString => \&generate_domstring_interface, DOMTimeStamp => "", DOMUserData => "", DOMObject =>"", ); our %special_type = ( # Some of the type are not defined now! boolean => "bool ", int => "int32_t ", "unsigned long" => "dom_ulong ", DOMString => "dom_string *", List => "list *", Collection => "list *", DOMImplementation => "dom_implementation *", NamedNodeMap => "dom_namednodemap *", NodeList => "dom_nodelist *", HTMLCollection => "dom_html_collection *", HTMLFormElement => "dom_html_form_element *", CharacterData => "dom_characterdata *", CDATASection => "dom_cdata_section *", HTMLAnchorElement => "dom_html_anchor_element *", HTMLElement => "dom_html_element *", HTMLTableCaptionElement => "dom_html_table_caption_element *", HTMLTableSectionElement => "dom_html_table_section_element *", HTMLTableElement => "dom_html_table_element *", HTMLTableRowElement => "dom_html_table_row_element *", HTMLOptionsCollection => "dom_html_options_collection *", ); our %special_prefix = ( DOMString => "dom_string", DOMImplementation => "dom_implementation", NamedNodeMap => "dom_namednodemap", NodeList => "dom_nodelist", HTMLCollection => "dom_html_collection", HTMLFormElement => "dom_html_form_element", CharacterData => "dom_characterdata", CDATASection => "dom_cdata_section *", HTMLHRElement => "dom_html_hr_element", HTMLBRElement => "dom_html_br_element", HTMLLIElement => "dom_html_li_element", HTMLTableCaptionElement => "dom_html_table_caption_element", HTMLTableSectionElement => "dom_html_table_section_element", HTMLIsIndexElement => "dom_html_isindex_element", HTMLIFrameElement => "dom_html_iframe_element", HTMLOListElement => "dom_html_olist_element", HTMLDListElement => "dom_html_dlist_element", caption => "dom_html_table_caption_element *", section => "dom_html_table_section_element *", createCaption => "dom_html_element *", createTHead => "dom_html_element *", createTFoot => "dom_html_element *", deleteCaption => "dom_html_element *", deleteTHead => "dom_html_element *", deleteTFoot => "dom_html_element *", insertRow => "dom_html_element *", deleteRow => "dom_html_element *", form => "dom_html_form_element *", ); our %unref_prefix = ( DOMString => "dom_string", NamedNodeMap => "dom_namednodemap", NodeList => "dom_nodelist", HTMLCollection => "dom_html_collection", HTMLOptionsCollection => "dom_html_options_collection", HTMLDocument => "dom_html_document", ); our %special_method = ( ); our %special_attribute = ( namespaceURI => "namespace", URL => "url", ); our %no_unref = ( "boolean" => 1, "int" => 1, "unsigned int" => 1, "unsigned long" => 1, "List" => 1, "Collection" => 1, ); our %override_suffix = ( boolean => "bool", int => "int", "unsigned long" => "unsigned_long", DOMString => "domstring", DOMImplementation => "domimplementation", NamedNodeMap => "domnamednodemap", NodeList => "domnodelist", HTMLCollection => "domhtmlcollection", Collection => "list", List => "list", ); our %exceptions = ( DOM_NO_ERR => 0, DOM_INDEX_SIZE_ERR => 1, DOM_DOMSTRING_SIZE_ERR => 2, DOM_HIERARCHY_REQUEST_ERR => 3, DOM_WRONG_DOCUMENT_ERR => 4, DOM_INVALID_CHARACTER_ERR => 5, DOM_NO_DATA_ALLOWED_ERR => 6, DOM_NO_MODIFICATION_ALLOWED_ERR => 7, DOM_NOT_FOUND_ERR => 8, DOM_NOT_SUPPORTED_ERR => 9, DOM_INUSE_ATTRIBUTE_ERR => 10, DOM_INVALID_STATE_ERR => 11, DOM_SYNTAX_ERR => 12, DOM_INVALID_MODIFICATION_ERR => 13, DOM_NAMESPACE_ERR => 14, DOM_INVALID_ACCESS_ERR => 15, DOM_VALIDATION_ERR => 16, DOM_TYPE_MISMATCH_ERR => 17, DOM_UNSPECIFIED_EVENT_TYPE_ERR => (1<<30)+0, DOM_DISPATCH_REQUEST_ERR => (1<<30)+1, DOM_NO_MEM_ERR => (1<<31)+0, ); our @condition = qw(same equals notEquals less lessOrEquals greater greaterOrEquals isNull notNull and or xor not instanceOf isTrue isFalse hasSize contentType hasFeature implementationAttribute); our @exception = qw(INDEX_SIZE_ERR DOMSTRING_SIZE_ERR HIERARCHY_REQUEST_ERR WRONG_DOCUMENT_ERR INVALID_CHARACTER_ERR NO_DATA_ALLOWED_ERR NO_MODIFICATION_ALLOWED_ERR NOT_FOUND_ERR NOT_SUPPORTED_ERR INUSE_ATTRIBUTE_ERR NAMESPACE_ERR UNSPECIFIED_EVENT_TYPE_ERR DISPATCH_REQUEST_ERR); our @assertion = qw(assertTrue assertFalse assertNull assertNotNull assertEquals assertNotEquals assertSame assertInstanceOf assertSize assertEventCount assertURIEquals); our @assertexception = qw(assertDOMException assertEventException assertImplementationException); our @control = qw(if while for-each else); our @framework_statement = qw(assign increment decrement append plus subtract mult divide load implementation comment hasFeature implementationAttribute EventMonitor.setUserObj EventMonitor.getAtEvents EventMonitor.getCaptureEvents EventMonitor.getBubbleEvents EventMonitor.getAllEvents wait); sub new { my $type = shift; my $dtd = shift; my $chdir = shift; my $dd = XML::XPath->new(filename => $dtd); my $self = { # The DTD file of the xml files dd => $dd, # To indicate whether we are in comments comment => 0, # To indicate that whether we are in <comment> element inline_comment => 0, # The stack of elements encountered utill now context => [], # The map for <var> name => type var => {}, # See the comment on generate_condition2 for this member condition_stack => [], # The list for UNREF unref => [], string_unref => [], block_unrefs => ["!!!"], # The indent of current statement indent => "", # The variables for List/Collection # We now, declare an array for a list and then add them into a list # The map for all the List/Collection in one test # "List Name" => "Member type" list_map => {}, # The name of the current List/Collection list_name => "", # The number of items of the current List/Collection list_last_name => [], # The number of items of the current List/Collection list_num => 0, # Whether List/Collection has members list_hasmem => 0, # The type of the current List/Collection member_list_declared => 0, # The type of the current List/Collection list_type => "", # Whether we are in exception assertion exception => 0, # Where to chdir chdir => $chdir }; return bless $self, $type; } sub start_element { my ($self, $element) = @_; my $en = $element->{Name}; my $dd = $self->{dd}; my $ct = $self->{context}; push(@$ct, $en); switch ($en) { case "test" { ; } case "metadata" { # start comments here print "/*\n"; $self->{comment} = 1; } # Print the var definition case "var" { $self->generate_var($element->{Attributes}); } case "member" { if ($self->{context}->[-2] eq "var") { if ($self->{"list_hasmem"} eq 1) { print ", "; } $self->{"list_hasmem"} = 1; $self->{"list_num"} ++; } } # The framework statements case [@framework_statement] { # Because the implementationAttribute & hasFeature belongs to both # framework-statement and condition, we should distinct the two # situation here. Let the generate_condtion to do the work. if ($en eq "hasFeature" || $en eq "implementationAttribute") { next; } $self->generate_framework_statement($en, $element->{Attributes}); } case [@control] { $self->generate_control_statement($en, $element->{Attributes}); } # Test condition case [@condition] { $self->generate_condition($en, $element->{Attributes}); } # The assertsions case [@assertion] { $self->generate_assertion($en, $element->{Attributes}); } case [@assertexception] { # Indeed, nothing to do here! } # Deal with exception case [@exception] { # Just see end_element $self->{'exception'} = 1; } # Then catch other case else { # we don't care the comment nodes if ($self->{comment} eq 0) { $self->generate_interface($en, $element->{Attributes}); } } } } sub end_element { my ($self, $element) = @_; my @ct = @{$self->{context}}; my $name = pop(@{$self->{context}}); switch ($name) { case "metadata" { print "*/\n"; $self->{comment} = 0; $self->generate_main(); } case "test" { $self->cleanup(); } case "var" { $self->generate_list(); } # End of condition case [@condition] { $self->complete_condition($name); } # The assertion case [@assertion] { $self->complete_assertion($name); } case [@control] { $self->complete_control_statement($name); } case [@exception] { $name = "DOM_".$name; print "assert(exp == $exceptions{$name});\n"; $self->{'exception'} = 0; } } } sub characters { my ($self, $data) = @_; our $description; my $ct = $self->{context}; if ($self->{"inline_comment"} eq 1) { print "$data->{Data}"; return ; } # We print the comments here if ($self->{comment} eq 1) { # So, we are in comments state my $top = $ct->[$#{$ct}]; if ($top eq "metadata") { return; } if ($top eq "description") { if ($description eq 0) { print "description: \n"; $description = 1; } print "$data->{Data}"; } else { print "$top: $data->{Data}\n"; } return; } if ($self->{context}->[-1] eq "member") { # We should mark that the List/Collection has members $self->{"list_hasmem"} = 1; # Here, we should detect the characters type # whether it is a integer or string (now, we only take care # of the two types, because I did not find any other type). if ($self->{"list_type"} eq "") { if ($data->{Data} =~ /^\"/) { $self->{"list_type"} = "char *"; print "const char *".$self->{"list_name"}."Array[] = \{ $data->{Data}"; } else { if ($data->{Data} =~ /^[0-9]+/) { $self->{"list_type"} = "int *"; print "int ".$self->{"list_name"}."Array[] = \{ $data->{Data}"; } else { die "Some data in the <member> we can't process: \"$data->{Data}\""; } } } else { # So, we must have known the type, just output the member print "$data->{Data}"; } } } sub generate_main { my $self = shift; # Firstly, push a new "b" to the string_unref list push(@{$self->{"string_unref"}}, "b"); print << "__EOF__" #include <stdio.h> #include <string.h> #include <stdbool.h> #include <unistd.h> #include <dom/dom.h> #include <dom/functypes.h> #include <domts.h> dom_implementation *doc_impl; int main(int argc, char **argv) { dom_exception exp; (void)argc; (void)argv; if (chdir("$self->{chdir}") < 0) { perror("chdir (\\"$self->{chdir})\\""); return 1; } int list_temp[100], count = -1; __EOF__ } # Note that, we have not just declare variables here # we should also define EventListener here! # I think this should be done after the EventListener design # is complete sub generate_var { my ($self, $ats) = @_; my $type = ""; my $dstring = ""; # For the case like <var name="v" type="DOMString" value="some some" if ($ats->{"type"} eq "DOMString" and exists $ats->{"value"}) { $dstring = $self->generate_domstring($ats->{"value"}); $ats->{"value"} = $dstring; } $type = type_to_ctype($ats->{"type"}); if ($type eq "") { print "Not implement this type now\n"; return; } print "\t$type$ats->{'name'}"; if (exists $ats->{"value"}) { print " = $ats->{'value'};\n"; } else { if ($type =~ m/\*/) { print " = NULL;\n"; } else { print ";\n"; } } my $var = $self->{"var"}; $var->{$ats->{"name"}} = $ats->{"type"}; # If the type is List/Collection, we should take care of it if ($ats->{"type"} =~ /^(List|Collection)$/) { $self->{"list_name"} = $ats->{"name"}; } } sub generate_list { my $self = shift; # We should deal with the end of <var> when the <var> is declaring a List/Collection if ($self->{"list_hasmem"} eq 1) { # Yes, we are in List/Collection declaration # Firstly, enclose the Array declaration print "};\n"; # Now, we should create the list * for the List/Collection # Note, we should deal with "int" or "string" type with different params. if ($self->{"list_type"} eq "char *") { print $self->{"list_name"}." = list_new(STRING);\n"; } if ($self->{"list_type"} eq "int *") { print $self->{"list_name"}." = list_new(INT);\n"; while(defined ($x = pop @{$self->{"list_last_name"}})) { print $x." = list_new(INT);\n"; } } while(defined($x = pop(@{$self->{"list_last_name"}}))) { print $x." = list_new(DOM_STRING);\n"; } $self->{"member_list_declared"} = 1; if ($self->{"list_type"} eq "") { die "A List/Collection has children member but no type is impossible!"; } if ($self->{"list_type"} eq "int *") { for (my $i = 0; $i < $self->{"list_num"}; $i++) { # Use *(char **) to convert char *[] to char * print "list_add(".$self->{"list_name"}.", (int *)(".$self->{"list_name"}."Array) + $i);\n"; }