in meta/xmlutils.pm [444:560]
sub ExtractStructInfoEx
{
my ($structName, $prefix) = @_;
LogDebug "processing struct/union $structName: prefix: $prefix";
my %Struct = (name => $structName);
my $filename = "${prefix}${structName}.xml";
$filename =~ s/_/__/g;
$filename = $prefix if -e "$main::XMLDIR/$prefix" and $prefix =~ /\.xml$/;
my $file = "$main::XMLDIR/$filename"; # example: xml/struct__sai__fdb__entry__t.xml
if (not -e $file)
{
$file =~ s/struct_/union_/;
}
# read xml, we need to get each struct field and it's type and description
my $ref = ReadXml $file;
my @sections = @{ $ref->{compounddef}[0]->{sectiondef} };
if (scalar @sections != 1)
{
LogError "expected only 1 section in $file for $structName";
return %Struct;
}
my @members = @{ $sections[0]->{memberdef} };
if (scalar @members < 1)
{
LogError "there must be at least 1 member in struct $structName";
return %Struct;
}
my $desc = ExtractDescription($structName, $structName, $ref->{compounddef}[0]->{detaileddescription}[0]);
ProcessStructDescription(\%Struct, $desc);
$Struct{desc} = $desc;
my $idx = 0;
my @StructMembers = ();
my @keys = ();
$Struct{count}->{list} = "count" if $structName =~ /^sai_(\w+)_list_t$/;
for my $member (@members)
{
my $name = $member->{name}[0];
my $type = $member->{definition}[0];
my $args = $member->{argsstring}[0];
my $file = $member->{location}[0]->{file};
LogDebug "processing member '$name' on $structName";
# if argstring is empty in xml, then it returns empty hash, skip this
# args contain extra arguments like [32] for "char foo[32]" or
# function parameters
$args = "" if ref $args eq "HASH";
$type = $1 if $type =~ /^(.+) _sai_\w+_t::(?:\w+|::)+(.*)$/;
my $typeSuffix = $2;
if ($typeSuffix ne "")
{
if ($typeSuffix =~ /^\[\d+\]$/)
{
$type .= $typeSuffix;
}
else
{
LogError "not supported type '$member->{definition}[0]'\n";
}
}
my $desc = ExtractDescription($structName, $name, $member->{detaileddescription}[0]);
my %M = ();
$M{count} = $Struct{count}->{$name} if defined $Struct{count}->{$name};
$M{type} = $type;
$M{desc} = $desc;
$M{args} = $args;
$M{file} = $file;
$M{name} = $name;
$M{idx} = $idx++;
$M{union} = $member->{type}[0]->{ref}[0]->{refid} if $member->{definition}[0] =~ /union /;
ProcessStructDescription(\%M, $desc);
$Struct{membersHash}{$name} = \%M;
push @StructMembers, \%M;
push @keys, $name;
$Struct{ismetadatastruct} = 1 if $file =~ m!meta/sai\w+.h$|saimeta\w+!;
$Struct{containsfnpointer} = 1 if $type =~ /^sai_\w+_fn$/;
}
$Struct{members} = \@StructMembers;
$Struct{keys} = \@keys;
$Struct{baseName} = ($structName =~ /^sai_(\w+)_t$/) ? $1 : $structName;
$Struct{baseName} =~ s/^_//;
$Struct{union} = 1 if $ref->{compounddef}[0]->{kind} eq "union";
return %Struct;
}