From 682321d1be0335769917f1800025235f667b6383 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Mon, 24 Feb 2025 16:27:07 +0100 Subject: [PATCH] ManUtils: Move, use ExtUtils::MakeMaker and get rid of AnyEvent I mean, I like AnyEvent, but this can be done with core modules as well (albeit somewhat more verbose and error-prone...) --- .gitignore | 8 +-- Makefile | 16 +++--- ManUtils/Makefile.PL | 10 ++++ ManUtils/ManUtils.pm | 68 ++++++++++++++++++++++++++ {lib/ManUtils => ManUtils}/ManUtils.xs | 0 README.md | 1 - lib/ManUtils/Build.PL | 18 ------- lib/ManUtils/ManUtils.pm | 67 ------------------------- www/index.pl | 10 ++-- 9 files changed, 92 insertions(+), 106 deletions(-) create mode 100644 ManUtils/Makefile.PL create mode 100644 ManUtils/ManUtils.pm rename {lib/ManUtils => ManUtils}/ManUtils.xs (100%) delete mode 100644 lib/ManUtils/Build.PL delete mode 100644 lib/ManUtils/ManUtils.pm diff --git a/.gitignore b/.gitignore index 072394c..f8c9a00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -/lib/ManUtils/* -!/lib/ManUtils/Build.PL -!/lib/ManUtils/ManUtils.pm -!/lib/ManUtils/ManUtils.xs +/ManUtils/* +!/ManUtils/Makefile.PL +!/ManUtils/ManUtils.pm +!/ManUtils/ManUtils.xs indexer/target web/target util/.config diff --git a/Makefile b/Makefile index 3ffb83b..c645eec 100644 --- a/Makefile +++ b/Makefile @@ -3,26 +3,24 @@ all: ManUtils indexer -ManUtils: lib/ManUtils/inst/lib/perl5/x86_64-linux/ManUtils.pm +ManUtils: ManUtils/blib/lib/ManUtils.pm -lib/ManUtils/inst/lib/perl5/x86_64-linux/ManUtils.pm: lib/ManUtils/Build.PL lib/ManUtils/ManUtils.pm lib/ManUtils/ManUtils.xs web/target/release/libweb.a - -test lib/ManUtils/ManUtils.xs -ot web/target/release/libweb.a && touch -r web/target/release/libweb.a lib/ManUtils/ManUtils.xs - cd lib/ManUtils && perl Build.PL && ./Build install --install-base=inst - touch lib/ManUtils/inst/lib/perl5/x86_64-linux/ManUtils.pm +ManUtils/blib/lib/ManUtils.pm: ManUtils/Makefile.PL ManUtils/ManUtils.pm ManUtils/ManUtils.xs web/target/release/libweb.a + -test ManUtils/ManUtils.xs -ot web/target/release/libweb.a && touch -r web/target/release/libweb.a ManUtils/ManUtils.xs + cd ManUtils && perl Makefile.PL && make + touch ManUtils/blib/lib/ManUtils.pm web/target/release/libweb.a: web/Cargo.toml web/src/*.rs cd web && cargo build --release #strip --strip-unneeded web/target/release/libweb.a - indexer: indexer/target/release/indexer indexer/target/release/indexer: indexer/Cargo.toml indexer/src/*.rs cd indexer && cargo build --release - clean: - cd lib/ManUtils && ./Build distclean - rm -rf lib/ManUtils/inst + make -C ManUtils clean + rm -f ManUtils/Makefile.old cd indexer && cargo clean cd web && cargo clean diff --git a/ManUtils/Makefile.PL b/ManUtils/Makefile.PL new file mode 100644 index 0000000..fc9d30c --- /dev/null +++ b/ManUtils/Makefile.PL @@ -0,0 +1,10 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'ManUtils', + VERSION_FROM => 'ManUtils.pm', + LICENSE => 'mit', + NO_MYMETA => 1, + MIN_PERL_VERSION => 'v5.36', + LDFROM => 'ManUtils.o ../web/target/release/libweb.a -lpthread', +); diff --git a/ManUtils/ManUtils.pm b/ManUtils/ManUtils.pm new file mode 100644 index 0000000..bf27d13 --- /dev/null +++ b/ManUtils/ManUtils.pm @@ -0,0 +1,68 @@ +package ManUtils 0.2; + +use v5.36; +use IPC::Open3; +use IO::Poll qw/POLLOUT POLLIN/; +use Symbol 'gensym'; +use XSLoader; +XSLoader::load('ManUtils'); + +sub fmt($input) { + my @cmd = 'groff'; + push @cmd, '-t' if $input =~ /^\.TS/m; + push @cmd, '-e' if $input =~ /^\.EQ/m; + # $MANWIDTH works by using the following groff options: -rLL=100n -rLT=100n + push @cmd, qw/-mandoc -Tutf8 -DUTF-8 -P-c -rLL=80n -rLT=80n -/; + + $input = + # Disable hyphenation, since that screws up man page references. :-( + ".hy 0\n.de hy\n..\n" + # Emulate man-db's --nj option + .".na\n.de ad\n..\n" + # Unbreak some quotes, there's plenty of man pages that ("incorrectly") use these for code samples. + .".char ` \\`\n" + .".char ' \\[aq]\n" + .$input; + utf8::encode($input); + + my $pid = open3(my $in, my $out, my $err = gensym, @cmd); + + my $inoff = 0; + my $output = ''; + my $poll = IO::Poll->new; + $poll->mask($in => POLLOUT); + $poll->mask($out => POLLIN); + $poll->mask($err => POLLIN); + while (1) { + $poll->poll; + + if ($poll->events($in)) { + my $r = syswrite $in, $input, 16*1024, $inoff; + die "Write error: $!\n" if $r <= 0; + $inoff += $r; + if ($inoff == length $input) { + $poll->remove($in); + close $in; + } + } + + if ($poll->events($out)) { + my $r = sysread $out, $output, 16*1024, length $output; + die "Read error: $!\n" if $r < 0; + if ($r == 0) { + utf8::decode($output); + waitpid $pid, 0; + die "Groff exited with $?\n" if $?; + return $output =~ s/\s+$//r; + } + } + + if ($poll->events($err)) { + my $r = sysread $err, my $buf, 16*1024; + $poll->remove($err) if $r == 0; + warn "GROFF: $buf\n" if $r > 0; + } + } +} + +1; diff --git a/lib/ManUtils/ManUtils.xs b/ManUtils/ManUtils.xs similarity index 100% rename from lib/ManUtils/ManUtils.xs rename to ManUtils/ManUtils.xs diff --git a/README.md b/README.md index 1d30d71..40e390c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ Ironically, documentation about how things work is completely lacking. ### Web front-end - FU -- AnyEvent ### Man page indexer diff --git a/lib/ManUtils/Build.PL b/lib/ManUtils/Build.PL deleted file mode 100644 index 04474c4..0000000 --- a/lib/ManUtils/Build.PL +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/perl - -use Module::Build; - -Module::Build->new( - dist_name => 'ManUtils', - dist_version_from => 'ManUtils.pm', - dist_abstract => 'Utils for manned.org', - license => 'MIT', - extra_linker_flags => '../../web/target/release/libweb.a -lpthread', - pm_files => { - 'ManUtils.pm' => 'lib/ManUtils.pm', - }, - xs_files => { - 'ManUtils.xs' => 'lib/ManUtils.xs', - }, -)->create_build_script; - diff --git a/lib/ManUtils/ManUtils.pm b/lib/ManUtils/ManUtils.pm deleted file mode 100644 index 3501b9a..0000000 --- a/lib/ManUtils/ManUtils.pm +++ /dev/null @@ -1,67 +0,0 @@ -package ManUtils; - -use strict; -use warnings; -use AE; -use AnyEvent::Util; -use Encode 'decode_utf8', 'encode_utf8'; - - -our $VERSION = '0.01'; - -require XSLoader; -XSLoader::load('ManUtils', $VERSION); - - -# Usage: $cv = fmt($input, \$output, \@errors) -# $cv = AnyEvent condition variable, fired when done. -# $input = UTF-8 encoded manual page source -# $output = variable that will hold the output when done -# @errors = list of warnings/errors while running groff -sub fmt { - my($input, $output, $errors) = @_; - $$output = ''; - @$errors = (); - - my @cmd = 'groff'; - push @cmd, '-t' if $input =~ /^\.TS/m; - push @cmd, '-e' if $input =~ /^\.EQ/m; - # $MANWIDTH works by using the following groff options: -rLL=100n -rLT=100n - push @cmd, qw/-mandoc -Tutf8 -DUTF-8 -P-c -rLL=80n -rLT=80n -/; - - $input = - # Disable hyphenation, since that screws up man page references. :-( - ".hy 0\n.de hy\n..\n" - # Emulate man-db's --nj option - .".na\n.de ad\n..\n" - # Unbreak some quotes, there's plenty of man pages that ("incorrectly") use these for code samples. - .".char ` \\`\n" - .".char ' \\[aq]\n" - .encode_utf8($input); - - my $groff = run_cmd \@cmd, - '<' => \$input, - '>' => $output, - '2>' => sub { if($_[0]) { chomp(my $e = $_[0]); push @$errors, "groff: $e" } }; - - my $cv = AE::cv; - $groff->cb(sub { - decode_utf8 $$output; - $$output =~ s/[\t\s\r\n]+$//; - $cv->send; - }); - $cv -} - - -# Blocking version of fmt(). Returns the formatted man page, errors are -# forwarded to warn(). -sub fmt_block { - my $c = shift; - my $cv = fmt $c, \my $out, \my @err; - $cv->recv; - #warn "$_\n" for @err; - $out; -} - -1; diff --git a/www/index.pl b/www/index.pl index a5738e4..08ec667 100755 --- a/www/index.pl +++ b/www/index.pl @@ -13,11 +13,7 @@ use Cwd 'abs_path'; our $ROOT; BEGIN { ($ROOT = abs_path $0) =~ s{/www/index\.pl$}{}; } -# Force the pure-perl AnyEvent backend; More lightweight and we don't need the -# performance of EV. -BEGIN { $ENV{PERL_ANYEVENT_MODEL} = 'Perl'; } - -use lib "$ROOT/lib/ManUtils/inst/lib/perl5"; +use lib "$ROOT/ManUtils/blib/lib", "$ROOT/ManUtils/blib/arch"; use ManUtils; @@ -740,7 +736,7 @@ sub man_page($man, $url) { fu->done; } - my $fmt = ManUtils::html ManUtils::fmt_block soelim $man->{verid}, $content; + my $fmt = ManUtils::html ManUtils::fmt soelim $man->{verid}, $content; if($url->{fmt} eq 'txt') { # TODO: The 'txt' format is kind of broken right now as it includes our HTML formatting codes. # This feature is a WIP and not advertised at the moment, anyway. @@ -981,7 +977,7 @@ FU::get qr{/pkg/([^/]+)/(.+)} => sub($short, $path) { FU::get qr{/browse/(.+)} => sub($pkg) { fu->redirect(perm => "/pkg/$pkg") }; # Redirect for the system selection box, for visitors who have disabled JS. -FU::get qr{/sysredir/([^/]+)} => sub($path) { fu->redirect(temp => '/man/'.(fu->query('system')//'arch')."/$path", 'temp') }; +FU::get qr{/sysredir/([^/]+)} => sub($path) { fu->redirect(temp => '/man/'.(fu->query('system')//'arch')."/$path") }; # Redirect for a specific language for a man page. I have no idea if anyone # still uses this URL format, but it was supported at some point, so let's keep