diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 12:52:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 12:52:13 +0000 |
commit | f8e5c55a036f0e2e2a958e30456270f3f9eba933 (patch) | |
tree | 4a06ff510774a7a3373e492df4e2984d7b0664b1 /scripts/unanon | |
parent | Initial commit. (diff) | |
download | sudo-upstream.tar.xz sudo-upstream.zip |
Adding upstream version 1.9.5p2.upstream/1.9.5p2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'scripts/unanon')
-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..5336825 --- /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); |