sub ExtractStructInfoEx()

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;
}