I've been playing with three scripts for identifying variables in the ports
tree and locating their doc.
I've attached all 3.
Basically: I go
make show=.VARIABLES | lister >fullwords
to extract every relevant public variable name from the tree.
The second script, locatewords, will try to find all variables in manpages.
Coincidentally, it's great at finding badly annotated variables !
The third script, mgrep, looks in MAKEFILE_LIST for a given construct,
helping the user figure out where a variable is defined/used
#! /usr/bin/perl
use v5.36;
my %hash;
my ($pkgpath, $fullpkgpath);
while (<>) {
chomp;
if (m/^\=\=\=\>\s+(.*)/) {
$fullpkgpath = $1;
$pkgpath = $fullpkgpath;
$pkgpath =~ s/,.*//;
say STDERR $pkgpath;
next;
}
for my $word (split /\s+/, $_) {
next if $word =~ m/^\_/;
next if $word eq "BULK_$pkgpath";
next if $word eq "BULK_DO_$pkgpath";
next if $word eq "BULK_TARGETS_$pkgpath";
next if $word eq "CLEANDEPENDS_$pkgpath";
next if $word eq "WRKOBJDIR_$pkgpath";
next if $word eq "FAKEOBJDIR_$pkgpath";
next if $word =~ m/^LIB.*_VERSION$/;
for my $w (qw(COMMENT PKG_ARCH PERMIT_PACKAGE PKGFILE
PKGNAME PKGSTEM FULLPKGNAME REVISION EPOCH FULLPKGPATH
RUN_DEPENDS WANTLIB LIB_DEPENDS IGNORE ONLY_FOR_ARCHS
NOT_FOR_ARCHS PKG_ARGS PREFIX CATEGORIES MESSAGE
UNMESSAGE DESCR PLIST STATIC_PLIST PKGSPEC SUBST_CMD)) {
$word =~ s/^(\Q$w\E)\-.*/$1/;
}
for my $w (qw(SITES DISTFILES SUPDISTFILES PATCHFILES
TEMPLATE_DISTFILES TEMPLATE_HOMEPAGE)) {
$word =~ s/^(\Q$w\E)\..*/$1/;
}
$hash{$word} //= $pkgpath;
}
}
for my $w (sort keys %hash) {
say "$w => $hash{$w}";
}
#! /usr/bin/perl
use v5.36;
my %keys;
sub find_manpage($man, $section)
{
my $f;
for my $d ("/usr/share/man/", "/usr/X11R6/man", "/usr/local/man") {
for my $try (split(/,\s+/, $man)) {
if (open($f, '<', "$d/man$section/$try.$section")) {
return $f;
}
}
}
return undef;
}
sub cache_file($man, $section)
{
my $f = find_manpage($man, $section);
if (!defined $f) {
say STDERR "Can't locate $man($section)";
return;
}
my $h = {};
while (<$f>) {
chomp;
if (m/^\.Ev\s+(.*)/) {
for my $word (split(/\s+/, $1)) {
$h->{$word} = 1;
}
} elsif (m/^\.It\s+Ev\s+(.*)/) {
for my $word (split(/\s+/, $1)) {
$h->{$word} = 1;
}
}
}
$keys{$man.$section} = $h;
close($f);
}
sub contains($man, $section, $ev)
{
if (!defined $keys{$man.$section}) {
cache_file($man, $section);
}
if ($keys{$man.$section}{$ev}) {
return 1;
} else {
return 0;
}
}
open(my $g, '<', "fullwords") or die;
while (<$g>) {
chomp;
if (m/^(.*)(\s\=\>.*)/) {
my ($var, $rest) = ($1, $2);
my @mans;
open(my $pipe, "man -k Ev=$var 2>/dev/null|");
while (<$pipe>) {
chomp;
if (m/^(.*)\((\dp?)\)\s+\-\s+/) {
my ($man, $section) = ($1, $2);
if (contains($man, $section, $var)) {
push(@mans, "$man($section)");
}
}
}
close($pipe);
if (@mans) {
say $var.' ('.join(', ', @mans).')'.$rest;
} else {
say $var.$rest;
}
}
}
#! /bin/sh
for i in `make show=MAKEFILE_LIST`
do
grep -l "$1" $i
done