2017-05-01 03:26:56 +03:00
#!/usr/bin/env python3
2013-02-03 07:47:47 +04:00
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
#
2017-04-05 06:21:04 +03:00
# Copyright 2013, 2017 Zbigniew Jędrzejewski-Szmek
2013-02-03 07:47:47 +04:00
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# systemd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import collections
import sys
2013-12-22 03:11:35 +04:00
import os . path
2017-04-05 06:21:04 +03:00
import pprint
2013-03-29 22:22:27 +04:00
from xml_helper import *
2013-02-03 07:47:47 +04:00
SECTION = ''' \
MANPAGES + = \\
{ manpages }
MANPAGES_ALIAS + = \\
{ aliases }
{ rules }
2013-03-08 20:03:50 +04:00
{ htmlrules }
2013-02-03 07:47:47 +04:00
'''
CONDITIONAL = ''' \
if { conditional }
''' \
+ SECTION + \
''' \
endif
'''
HEADER = ''' \
# Do not edit. Generated by make-man-rules.py.
2014-03-07 08:24:30 +04:00
# To regenerate:
# 1. Create, update, or remove source .xml files in man/
# 2. Run 'make update-man-list'
# 3. Run 'make man' to generate manpages
#
# To make a man page conditional on a configure switch add
# attribute conditional="ENABLE_WHAT" or conditional="WITH_WHAT"
# to <refentry> element.
2013-02-03 07:47:47 +04:00
'''
2013-03-08 20:03:50 +04:00
HTML_ALIAS_RULE = ''' \
{ } . html : { } . html
$ ( html - alias )
'''
2013-12-22 03:11:35 +04:00
FOOTER = ''' \
2014-03-07 08:24:30 +04:00
# Really, do not edit this file.
2013-12-22 03:11:35 +04:00
EXTRA_DIST + = \\
2015-06-30 16:56:44 +03:00
{ dist_files }
2013-12-22 03:11:35 +04:00
'''
2017-04-05 06:21:04 +03:00
meson = False
2013-02-03 07:47:47 +04:00
def man ( page , number ) :
2017-04-05 06:21:04 +03:00
return ( ' man/ ' if not meson else ' ' ) + ' {} . {} ' . format ( page , number )
2013-02-03 07:47:47 +04:00
2013-12-22 03:11:35 +04:00
def xml ( file ) :
2017-04-05 06:21:04 +03:00
return ( ' man/ ' if not meson else ' ' ) + os . path . basename ( file )
2013-12-22 03:11:35 +04:00
2013-02-03 07:47:47 +04:00
def add_rules ( rules , name ) :
2013-03-29 22:22:27 +04:00
xml = xml_parse ( name )
2013-02-03 07:47:47 +04:00
# print('parsing {}'.format(name), file=sys.stderr)
2014-02-20 01:06:10 +04:00
if xml . getroot ( ) . tag != ' refentry ' :
return
2013-02-03 07:47:47 +04:00
conditional = xml . getroot ( ) . get ( ' conditional ' ) or ' '
rulegroup = rules [ conditional ]
refmeta = xml . find ( ' ./refmeta ' )
title = refmeta . find ( ' ./refentrytitle ' ) . text
number = refmeta . find ( ' ./manvolnum ' ) . text
refnames = xml . findall ( ' ./refnamediv/refname ' )
target = man ( refnames [ 0 ] . text , number )
if title != refnames [ 0 ] . text :
raise ValueError ( ' refmeta and refnamediv disagree: ' + name )
for refname in refnames :
assert all ( refname not in group
for group in rules . values ( ) ) , " duplicate page name "
alias = man ( refname . text , number )
rulegroup [ alias ] = target
# print('{} => {} [{}]'.format(alias, target, conditional), file=sys.stderr)
2013-12-22 03:11:35 +04:00
def create_rules ( xml_files ) :
2013-02-03 07:47:47 +04:00
" { conditional => { alias-name => source-name}} "
rules = collections . defaultdict ( dict )
for name in xml_files :
2014-02-20 01:06:10 +04:00
try :
add_rules ( rules , name )
except Exception :
print ( " Failed to process " , name , file = sys . stderr )
raise
2013-02-03 07:47:47 +04:00
return rules
def mjoin ( files ) :
return ' \\ \n \t ' . join ( sorted ( files ) or ' # ' )
2015-06-30 16:56:44 +03:00
def make_makefile ( rules , dist_files ) :
2013-02-03 07:47:47 +04:00
return HEADER + ' \n ' . join (
( CONDITIONAL if conditional else SECTION ) . format (
manpages = mjoin ( set ( rulegroup . values ( ) ) ) ,
aliases = mjoin ( k for k , v in rulegroup . items ( ) if k != v ) ,
rules = ' \n ' . join ( ' {} : {} ' . format ( k , v )
for k , v in sorted ( rulegroup . items ( ) )
if k != v ) ,
2013-03-08 20:03:50 +04:00
htmlrules = ' \n ' . join ( HTML_ALIAS_RULE . format ( k [ : - 2 ] , v [ : - 2 ] )
for k , v in sorted ( rulegroup . items ( ) )
if k != v ) ,
2013-02-03 07:47:47 +04:00
conditional = conditional )
2013-12-22 03:11:35 +04:00
for conditional , rulegroup in sorted ( rules . items ( ) )
2015-06-30 16:56:44 +03:00
) + FOOTER . format ( dist_files = mjoin ( sorted ( dist_files ) ) )
2013-02-03 07:47:47 +04:00
2017-04-05 06:21:04 +03:00
MESON_HEADER = ''' \
# Do not edit. Generated by make-man-rules.py.
manpages = [ '''
MESON_FOOTER = ''' \
]
# Really, do not edit.'''
def make_mesonfile ( rules , dist_files ) :
# reformat rules as
# grouped = [ [name, section, [alias...], condition], ...]
#
# but first create a dictionary like
# lists = { (name, condition) => [alias...]
grouped = collections . defaultdict ( list )
for condition , items in rules . items ( ) :
for alias , name in items . items ( ) :
group = grouped [ ( name , condition ) ]
if name != alias :
group . append ( alias )
lines = [ [ p [ 0 ] [ : - 2 ] , p [ 0 ] [ - 1 ] , sorted ( a [ : - 2 ] for a in aliases ) , p [ 1 ] ]
for p , aliases in sorted ( grouped . items ( ) ) ]
return ' \n ' . join ( ( MESON_HEADER , pprint . pformat ( lines ) [ 1 : - 1 ] , MESON_FOOTER ) )
2013-02-03 07:47:47 +04:00
if __name__ == ' __main__ ' :
2017-04-05 06:21:04 +03:00
meson = sys . argv [ 1 ] == ' --meson '
pages = sys . argv [ 1 + meson : ]
rules = create_rules ( pages )
dist_files = ( xml ( file ) for file in pages
2015-06-30 16:56:44 +03:00
if not file . endswith ( " .directives.xml " ) and
not file . endswith ( " .index.xml " ) )
2017-04-05 06:21:04 +03:00
if meson :
print ( make_mesonfile ( rules , dist_files ) )
else :
print ( make_makefile ( rules , dist_files ) , end = ' ' )