diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 13:14:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 13:14:46 +0000 |
commit | 025c439e829e0db9ac511cd9c1b8d5fd53475ead (patch) | |
tree | fa6986b4690f991613ffb97cea1f6942427baf5d /scripts/unanon | |
parent | Initial commit. (diff) | |
download | sudo-025c439e829e0db9ac511cd9c1b8d5fd53475ead.tar.xz sudo-025c439e829e0db9ac511cd9c1b8d5fd53475ead.zip |
Adding upstream version 1.9.15p5.upstream/1.9.15p5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | scripts/unanon | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/scripts/unanon b/scripts/unanon new file mode 100755 index 0000000..2bbb3c8 --- /dev/null +++ b/scripts/unanon @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +# +# Post-process files generated by protoc-c to remove anonymous unions. +# Works on the generated files but probably little else. + +use warnings; +use strict; + +sub unanon { + my $hfile = shift; + my $cfile = shift; + my ($fh, $content); + my %members; + + open $fh, "<", $hfile or die $!; + local $/; # enable localized slurp mode + $content = <$fh>; + close $fh; + + # Detect and replace anonymous unions in .h file. + # Assumes there is only one anonymous union in scope. + while ($content =~ s/^(struct\s+(\w+)[^}]+)(union\s+{([^}]+)}\s*);/$1$3 u;/sm) { + my $s = $2; + my $u = $4; + $u =~ s:/\*((?!\*/).)*\*/::sg; + foreach (split(/\n+/, $u)) { + if (/^.*\s+\**([^;]+);/) { + $members{$1} = $s; + } + } + } + open $fh, ">", $hfile or die $!; + print $fh $content; + close $fh; + + # Replace anonymous union access in generated .c file. + open $fh, "<", $cfile or die $!; + $content = <$fh>; + close $fh; + + while (my ($key, $val) = each %members) { + # We only support access via offsetof() + $content =~ s/offsetof\($val, $key\)/offsetof($val, u.$key)/g; + } + open $fh, ">", $cfile or die $!; + print $fh $content; + close $fh; +} + +unanon(@ARGV); |