Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 113 additions & 45 deletions meta/parse.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5294,68 +5294,136 @@ sub CreateSourcePragmaPop
WriteSource "#pragma GCC diagnostic pop";
}

sub GetDoxygenVersion
sub NeedsTwoPassProcessing
{
# Try running doxygen --version
my $version = `doxygen --version 2>/dev/null`;
chomp $version;
return $version if $version =~ /^\d+\.\d+\.\d+$/;
#
# Detect if XML files require two-pass processing based on their structure.
#
# In Doxygen 1.9.8+, the XML structure changed:
# - sai_*.xml files have empty enum/define sections (just sectiondef exists, no memberdefs)
# - group_*.xml files contain the actual enum definitions with enumvalues and defines
#
# In older Doxygen versions:
# - sai_*.xml files contain both defines and enums with enumvalues
# - group_*.xml files don't exist or aren't used
#
# Returns 1 if two-pass processing is needed (new structure):
# - First pass: process all defines from group_*.xml files
# - Second pass: process enums/typedefs/functions from group_*.xml and sai_*.xml files
#
# Returns 0 if single-pass processing is sufficient (old structure):
# - Process sai_*.xml files only
#

return undef;
}
my $sai_file = "$XMLDIR/sai_8h.xml";

sub ProcessXmlFiles
{
my $doxygen_version = GetDoxygenVersion();
my $use_group_files = 0;

if (defined $doxygen_version) {
# Doxygen 1.9.8+ puts enum definitions in group_*.xml files instead of sai*_8h.xml
# Compare version: 1.9.8 or higher
if ($doxygen_version =~ /^(\d+)\.(\d+)\.(\d+)$/) {
my ($major, $minor, $patch) = ($1, $2, $3);
# Convert to comparable number: major*10000 + minor*100 + patch
my $version_num = $major * 10000 + $minor * 100 + $patch;
if ($version_num >= 10908) {
$use_group_files = 1;
LogInfo "Doxygen version $doxygen_version detected - using group_*.xml files";
} else {
LogInfo "Doxygen version $doxygen_version detected - using legacy sai*_8h.xml files only";
my $saiacl_file = "$XMLDIR/saiacl_8h.xml";

return 1 if not -f $sai_file or not -f $saiacl_file;

#
# Check sai_8h.xml for enumvalue with name="SAI_API_SWITCH"
#

my $sai_ref = ReadXml $sai_file;

return 1 if not defined $sai_ref->{compounddef}[0];

my @sai_sections = @{ $sai_ref->{compounddef}[0]->{sectiondef} };

my $has_enumvalue = 0;

for my $section (@sai_sections)
{
next if not $section->{kind} eq "enum";

for my $memberdef (@{ $section->{memberdef} })
{
next if not $memberdef->{kind} eq "enum";

if (defined $memberdef->{enumvalue})
{
for my $enumvalue (@{ $memberdef->{enumvalue} })
{
if (defined $enumvalue->{name} and defined $enumvalue->{name}[0] and $enumvalue->{name}[0] eq "SAI_API_SWITCH")
{
$has_enumvalue = 1;

last;
}
}
}
}

last if $has_enumvalue;
}

if ($use_group_files) {
# Doxygen 1.9.8+ approach: two-pass processing
# We need to process #defines BEFORE enums that reference them
my @all_files = ();
push @all_files, glob("$XMLDIR/group_*.xml");
push @all_files, map { "$XMLDIR/$_" } GetSaiXmlFiles($XMLDIR);
#
# Check saiacl_8h.xml for memberdef kind="define"
#

# PASS 1: Process ONLY #define sections from all files
for my $fullpath (@all_files) {
my $file = $fullpath;
$file =~ s/^.*\///;
LogInfo "Processing $file (defines pass)";
ProcessXmlFileDefinesOnly($fullpath);
my $saiacl_ref = ReadXml $saiacl_file;

return 1 if not defined $saiacl_ref->{compounddef}[0];

my @saiacl_sections = @{ $saiacl_ref->{compounddef}[0]->{sectiondef} };

my $has_define = 0;

for my $section (@saiacl_sections)
{
next if not $section->{kind} eq "define";

for my $memberdef (@{ $section->{memberdef} })
{
if ($memberdef->{kind} eq "define")
{
$has_define = 1;

last;
}
}

# PASS 2: Process everything else (enums, typedefs, functions)
for my $fullpath (@all_files) {
my $file = $fullpath;
$file =~ s/^.*\///;
LogInfo "Processing $file";
ProcessXmlFile($fullpath);
last if $has_define;
}

#
# If sai_8h.xml has enumvalues and saiacl_8h.xml has defines, it's old structure (single-pass)
# Otherwise, use two-pass processing (group_*.xml files contain the actual content)
#

return not ($has_enumvalue and $has_define);
}

sub ProcessXmlFiles
{
if (NeedsTwoPassProcessing())
{
LogInfo "New XML structure detected, proceeding with 2 pass processing";

my @group_files = GetGroupXmlFiles($XMLDIR);

for my $file (@group_files)
{
LogInfo "Processing $file (defines pass)";

ProcessXmlFileDefinesOnly("$XMLDIR/$file");
}
} else {
# Legacy approach: single-pass, only sai*_8h.xml files
for my $file (GetSaiXmlFiles($XMLDIR))

for my $file (@group_files)
{
LogInfo "Processing $file";

ProcessXmlFile("$XMLDIR/$file");
}
}

for my $file (GetSaiXmlFiles($XMLDIR))
{
LogInfo "Processing $file";

ProcessXmlFile("$XMLDIR/$file");
}
}

sub ProcessXmlFileDefinesOnly
Expand Down
11 changes: 10 additions & 1 deletion meta/xmlutils.pm
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,15 @@ sub GetXmlUnionFiles
return grep { /^union_\w*\.xml$/ } @files;
}

sub GetGroupXmlFiles
{
my $dir = shift;

my @files = GetXmlFiles($dir);

return grep { /^group__\w+\.xml$/ } @files;
}

sub ProcessStructCount
{
my ($structName, $tagValue, $previousTagValue) = @_;
Expand Down Expand Up @@ -626,7 +635,7 @@ BEGIN
{
our @ISA = qw(Exporter);
our @EXPORT = qw/
ReadXml UnescapeXml GetSaiXmlFiles GetXmlUnionFiles
ReadXml UnescapeXml GetSaiXmlFiles GetXmlUnionFiles GetGroupXmlFiles
ExtractDescription ExtractStructInfo ExtractStructInfoEx
/;
}
Expand Down