#!/usr/bin/env perl # # Figure out which subsystems are in use and suggest --disable-SUBSYSTEM switch # for those not in use. # # Copyright (c) 2016-2024, Jani Salonen # All rights reserved. # use utf8; use warnings; # %DEFS = ( 'engine/menu_defs.h' => 'menu', 'engine/widget_defs.h' => 'widget' ); %FUNC = (); %USES = (); %PROG = (); # Get the main source file to be parsed later # binmode(STDOUT, ":utf8"); open(FILE, '<:encoding(UTF-8)', "engine/dsl_ano.h") || die("Failed to open engine/dsl_ano.h: " . $!); my @f = ; close(FILE); # Construct subsystem hash table from function names # open(FILE, '<:encoding(UTF-8)', "engine/dynload_ret.h") || die("Failed to open engine/dynload_ret.h: " . $!); my @g = ; close(FILE); foreach my $g (@g) { $g =~ s/\r|\n//g; next unless($g); if($g =~ /"\w+",.*?\/\*\s+\w+\s+\*\//) { my $h = $g; $g =~ s/^.*?"//; $g =~ s/".*$//; $h =~ s/^.*\/\*\s+//; $h =~ s/\s+.*$//; $FUNC{$g} = $h; $USES{$h} = 1; } } # Get disableable subsystems from configure.ac # open(FILE, '<:encoding(UTF-8)', "configure.ac") || die("Failed to open configure.ac: " . $!); my @h = ; close(FILE); foreach my $h (@h) { $h =~ s/\r|\n//g; next unless($h); if($h =~ /-DPROG_DISABLE_/) { $h =~ s/^.*-DPROG_DISABLE_//; $h =~ s/".*$//; $PROG{lc($h)} = 1; } } # Get subsystem out from to-be-disabled-hash if its _defs.h file has something useful # while((my $k, $v) = each %DEFS) { open(FILE, '<:encoding(UTF-8)', "$k") || die("Failed to open " . $k . ": " . $!); my @t = ; close(FILE); my @c = grep(/^\/\*.*\s+items\s+processed.*\*\//, @t); if($c[0] && $c[0] ne "") { $c[0] =~ s/\r|\n//g; $c[0] =~ s/^\/\*\s+//; $c[0] =~ s/\s.*$//; if($c[0] != 0) { $USES{$v} = 0 if($USES{$v}); } } } # Figure out which subsystems can be disabled... # my $k = 0; for(my $i = 0; $i < @f; $i++) { $f[$i] =~ s/\r|\n//g; next unless($f[$i]); if(($k == 0 || $k == 2) && $f[$i] =~ /^static\s+struct\s+dsl_cmd_func_s\s+.*?\s+=\s+{$/) { $k = 1; } elsif($k == 1 && $f[$i] =~ /^};$/) { $k = 0; } elsif($k == 1) { $f[$i] =~ s/^.*?"//; $f[$i] =~ s/".*$//; $USES{$FUNC{$f[$i]}} = 0 if($FUNC{$f[$i]}); $k = 2; } } # ...and output list of subsystems # my $c = 0; my $d = 0; while((my $k, $v) = each %USES) { $d++ if(($PROG{$k} && $PROG{$k} == 1) && $v == 1); } foreach my $k (sort { lc($a) cmp lc($b) } keys %USES) { if(($PROG{$k} && $PROG{$k} == 1) && $USES{$k} == 1) { if($c == 0) { print STDOUT "" . "According to source files, there is some unused subsystems. You may consider" . "\n" . "disabling those subsystems to reduce executable size. Please supply following" . "\n" . "options to configure script if you haven't done so yet:" . "\n\n"; } print STDOUT " --disable-" . $k; if(($c + 1) != $d) { print STDOUT " \\" . "\n"; } else { print STDOUT "\n"; } $c++; } } print STDOUT "\n" if($c != 0); exit(0);