1#!/usr/local/bin/perl -w
2
3# $Id: makeman.pl 312 2008-06-15 18:09:42Z Joerg Mayer $
4
5# Written by Wolfram Sang (wolfram@the-dreams.de) in 2007,
6# some inspiration from help2man by Brendan O'Dea and from Perl::Critic
7
8# Generate the vpnc-manpage from a template and the --long-help-output.
9# Version 0.2
10
11# Command-line options: none
12# Files needed        : ./vpnc ./vpnc.8.template ./VERSION
13# Files created       : ./vpnc.8
14# Exit status         : errno-values or 255 (Magic string not found)
15
16# Distributed under the same licence as vpnc.
17
18use strict;
19use Fatal    qw(open close);
20use filetest qw(access);	# to always get errno-values on filetests
21use POSIX    qw(strftime setlocale LC_ALL);
22
23my $vpnc = './vpnc';
24-e $vpnc or die "$0: Can't find $vpnc. Did you compile it?\n";
25-x $vpnc or die "$0: Can't execute $vpnc. Please check permissions.\n";
26
27# The code converting the help-output to manpage format is lots of
28# regex-fiddling, sorry. It got a bit more complicated by additionally
29# indenting lists (those originally starting with an asterisk). I hope
30# this pays off when converting the manpage to HTML or such.
31
32open my $LONGHELP, '-|', "$vpnc --long-help";
33my $vpnc_options    = '';
34my $relative_indent = 0;
35my $indent_needed   = 0;
36
37while (<$LONGHELP>) {
38    if (/^  /) {
39
40	# Check if additional indent needs to be finished by comparing the
41	# amount of spaces at the beginning. A bit ugly, but I don't see a
42	# better way to do it.
43	if ($relative_indent) {
44	    /^( *)/;
45	    if (length($1) < $relative_indent) {
46		$vpnc_options .= ".RE\n";
47		$relative_indent = 0;
48		$indent_needed = 1;
49	    }
50	}
51
52	# Highlight the option and make an optional argument italic.
53	if (s/^ *(--[\w-]+)/\n.TP\n.BI "$1"/) {
54	    s/(<.+>)/ " $1"/;
55	}
56
57	# Highlight conffile-only options.
58	s/^ *(\(configfile only option\))/\n.TP\n.B $1/;
59
60	# Position the Default-string
61	s/^ *(Default:)/.IP\n$1/;
62
63	# Highlight the conf-variable and make an optional argument italic.
64	if (s/^ *(conf-variable:) (.+?) ?([<\n])/.P\n$1\n.BI "$2"$3/) {
65	    s/(<.+>)/ " $1"/;
66	}
67
68	# Replace asterisk with bulletin; indent if needed.
69	if (s/^( +)\* /.IP \\(bu\n/) {
70	    if (not $relative_indent) {
71		$vpnc_options .= ".RS\n";
72	        $relative_indent = length $1;
73	    }
74	}
75
76	# Do we need to add an .IP-command after .RE or is there already one?
77	if ($indent_needed and not /^\n?\.[TI]?P/) {
78	    $vpnc_options .= ".IP\n";
79	    $indent_needed = 0;
80	}
81
82	# Finalize string and add it to buffer
83        s/^ *//;
84	s/ *$//;
85	s/-/\\-/g;
86        $vpnc_options .= $_;
87    }
88}
89close $LONGHELP;
90
91# Hopefully the code speaks for itself from now on...
92
93setlocale( LC_ALL, 'C' );
94my $date = strftime( '%B %Y', localtime );
95
96open my $VERSION, '<', './VERSION';
97my $vpnc_version = <$VERSION>;
98close $VERSION;
99chomp $vpnc_version;
100
101open my $TEMPLATE, '<', './vpnc.8.template';
102open my $MANPAGE , '>', './vpnc.8';
103my $magic_found;
104my $MAGIC_FOR_HEADER  = qq(.\\" ###makeman.pl: Replace header here!\n);
105my $MAGIC_FOR_OPTIONS = qq(.\\" ###makeman.pl: Insert options from help-output here!\n);
106
107# Skip the template-header
108while (<$TEMPLATE>) {
109    last if ($magic_found = ($_ eq $MAGIC_FOR_HEADER));
110}
111die "$0: Missing magic: $MAGIC_FOR_HEADER" if not $magic_found;
112
113print {$MANPAGE} <<"END_MANPAGE_HEADER";
114.\\" This manpage is generated!
115.\\" Please edit the template-file in the source-distribution only.
116.TH VPNC "8" "$date" "vpnc version $vpnc_version" "System Administration Utilities"
117END_MANPAGE_HEADER
118
119$magic_found = 0;
120
121while (<$TEMPLATE>) {
122    if ($_ ne $MAGIC_FOR_OPTIONS) {
123	print {$MANPAGE} $_;
124    } else {
125	print {$MANPAGE} $vpnc_options;
126	$magic_found = 1;
127    }
128}
129die "$0: Missing magic: $MAGIC_FOR_OPTIONS" if not $magic_found;
130
131close $TEMPLATE;
132close $MANPAGE;
133