2012-11-13 21:39:18 +04:00
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
#
2013-01-26 19:47:16 +04:00
# Copyright 2012-2013 Zbigniew Jędrzejewski-Szmek
2012-11-13 21:39:18 +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/>.
2012-08-09 20:08:14 +04:00
import sys
import collections
2013-01-26 19:47:16 +04:00
import re
2013-03-29 22:22:27 +04:00
from xml_helper import *
2013-05-30 06:31:20 +04:00
from copy import deepcopy
2012-08-09 20:08:14 +04:00
TEMPLATE = ''' \
2013-02-03 07:47:47 +04:00
< refentry id = " systemd.directives " conditional = " HAVE_PYTHON " >
2012-08-09 20:08:14 +04:00
< refentryinfo >
< title > systemd . directives < / title >
< productname > systemd < / productname >
< authorgroup >
< author >
< contrib > Developer < / contrib >
< firstname > Zbigniew < / firstname >
< surname > Jędrzejewski - Szmek < / surname >
< email > zbyszek @in.waw.pl < / email >
< / author >
< / authorgroup >
< / refentryinfo >
< refmeta >
< refentrytitle > systemd . directives < / refentrytitle >
2013-01-15 07:08:33 +04:00
< manvolnum > 7 < / manvolnum >
2012-08-09 20:08:14 +04:00
< / refmeta >
< refnamediv >
< refname > systemd . directives < / refname >
< refpurpose > Index of configuration directives < / refpurpose >
< / refnamediv >
< refsect1 >
< t itle > Unit directives < / title >
< para > Directives for configuring units , used in unit
files . < / para >
< variablelist id = ' unit-directives ' / >
< / refsect1 >
2012-09-16 13:11:34 +04:00
2013-01-15 06:58:22 +04:00
< refsect1 >
< title > Options on the kernel command line < / title >
< para > Kernel boot options for configuring the behaviour of the
systemd process . < / para >
2013-01-26 19:47:16 +04:00
< variablelist id = ' kernel-commandline-options ' / >
2013-01-15 06:58:22 +04:00
< / refsect1 >
< refsect1 >
< title > Environment variables < / title >
2013-01-26 19:47:16 +04:00
< para > Environment variables understood by the systemd
manager and other programs . < / para >
2013-01-15 06:58:22 +04:00
< variablelist id = ' environment-variables ' / >
< / refsect1 >
2012-09-16 13:11:34 +04:00
< refsect1 >
< title > UDEV directives < / title >
< para > Directives for configuring systemd units through the
udev database . < / para >
< variablelist id = ' udev-directives ' / >
< / refsect1 >
2012-08-10 21:35:43 +04:00
2013-11-10 22:33:18 +04:00
< refsect1 >
< title > Network directives < / title >
< para > Directives for configuring network links through the
2013-11-10 23:52:53 +04:00
net - setup - link udev builtin and networks through
systemd - networkd . < / para >
2013-11-10 22:33:18 +04:00
< variablelist id = ' network-directives ' / >
< / refsect1 >
2012-08-10 21:35:43 +04:00
< refsect1 >
2013-01-26 19:47:16 +04:00
< title > Journal fields < / title >
2012-08-10 21:35:43 +04:00
2013-01-26 19:47:16 +04:00
< para > Fields in the journal events with a well known meaning . < / para >
2012-08-10 21:35:43 +04:00
< variablelist id = ' journal-directives ' / >
< / refsect1 >
2013-01-15 05:18:36 +04:00
2013-01-26 19:47:16 +04:00
< refsect1 >
< title > PAM configuration directives < / title >
< para > Directives for configuring PAM behaviour . < / para >
< variablelist id = ' pam-directives ' / >
< / refsect1 >
< refsect1 >
2014-06-30 17:27:16 +04:00
< title > < filename > / etc / crypttab < / filename > and
< filename > / etc / fstab < / filename > options < / title >
2013-01-26 19:47:16 +04:00
< para > Options which influence mounted filesystems and
encrypted volumes . < / para >
2014-06-30 17:27:16 +04:00
< variablelist id = ' fstab-options ' / >
2013-01-26 19:47:16 +04:00
< / refsect1 >
< refsect1 >
< title > System manager directives < / title >
< para > Directives for configuring the behaviour of the
systemd process . < / para >
< variablelist id = ' systemd-directives ' / >
< / refsect1 >
2013-01-15 05:18:36 +04:00
< refsect1 >
< title > bootchart . conf directives < / title >
< para > Directives for configuring the behaviour of the
systemd - bootchart process . < / para >
< variablelist id = ' bootchart-directives ' / >
< / refsect1 >
2013-01-15 06:34:19 +04:00
2013-01-26 19:47:16 +04:00
< refsect1 >
2014-11-06 22:06:30 +03:00
< title > command line options < / title >
2013-01-26 19:47:16 +04:00
< para > Command - line options accepted by programs in the
systemd suite . < / para >
< variablelist id = ' options ' / >
< / refsect1 >
2013-06-27 03:48:19 +04:00
< refsect1 >
< title > Constants < / title >
< para > Various constant used and / or defined by systemd . < / para >
< variablelist id = ' constants ' / >
< / refsect1 >
2013-01-26 19:47:16 +04:00
< refsect1 >
< title > Miscellaneous options and directives < / title >
< para > Other configuration elements which don ' t fit in
any of the above groups . < / para >
< variablelist id = ' miscellaneous ' / >
< / refsect1 >
2013-02-14 06:51:31 +04:00
< refsect1 >
< title > Files and directories < / title >
< para > Paths and file names referred to in the
documentation . < / para >
< variablelist id = ' filenames ' / >
< / refsect1 >
2013-01-15 06:34:19 +04:00
< refsect1 >
< title > Colophon < / title >
< para id = ' colophon ' / >
< / refsect1 >
2012-08-09 20:08:14 +04:00
< / refentry >
'''
2013-01-15 06:34:19 +04:00
COLOPHON = ''' \
This index contains { count } entries in { sections } sections ,
referring to { pages } individual manual pages .
'''
2013-01-26 20:27:35 +04:00
def _extract_directives ( directive_groups , formatting , page ) :
2013-03-29 22:22:27 +04:00
t = xml_parse ( page )
2012-08-09 20:08:14 +04:00
section = t . find ( ' ./refmeta/manvolnum ' ) . text
pagename = t . find ( ' ./refmeta/refentrytitle ' ) . text
2013-02-14 06:51:31 +04:00
storopt = directive_groups [ ' options ' ]
2012-08-09 20:08:14 +04:00
for variablelist in t . iterfind ( ' .//variablelist ' ) :
2013-01-26 19:47:16 +04:00
klass = variablelist . attrib . get ( ' class ' )
storvar = directive_groups [ klass or ' miscellaneous ' ]
# <option>s go in OPTIONS, unless class is specified
for xpath , stor in ( ( ' ./varlistentry/term/varname ' , storvar ) ,
( ' ./varlistentry/term/option ' ,
storvar if klass else storopt ) ) :
for name in variablelist . iterfind ( xpath ) :
text = re . sub ( r ' ([= ]).* ' , r ' \ 1 ' , name . text ) . rstrip ( )
stor [ text ] . append ( ( pagename , section ) )
2013-01-26 20:27:35 +04:00
if text not in formatting :
# use element as formatted display
2013-02-28 06:31:02 +04:00
if name . text [ - 1 ] in ' = ' :
name . clear ( )
else :
name . tail = ' '
2013-01-26 20:27:35 +04:00
name . text = text
formatting [ text ] = name
2012-08-09 20:08:14 +04:00
2013-02-14 06:51:31 +04:00
storfile = directive_groups [ ' filenames ' ]
2013-05-03 08:55:20 +04:00
for xpath , absolute_only in ( ( ' .//refsynopsisdiv//filename ' , False ) ,
( ' .//refsynopsisdiv//command ' , False ) ,
( ' .//filename ' , True ) ) :
2013-02-14 06:51:31 +04:00
for name in t . iterfind ( xpath ) :
2013-05-03 08:55:20 +04:00
if absolute_only and not ( name . text and name . text . startswith ( ' / ' ) ) :
continue
if name . attrib . get ( ' noindex ' ) :
continue
2013-02-14 06:51:31 +04:00
name . tail = ' '
if name . text :
2013-05-03 08:55:20 +04:00
if name . text . endswith ( ' * ' ) :
name . text = name . text [ : - 1 ]
2013-02-14 06:51:31 +04:00
if not name . text . startswith ( ' . ' ) :
text = name . text . partition ( ' ' ) [ 0 ]
if text != name . text :
name . clear ( )
name . text = text
2013-05-03 08:55:20 +04:00
if text . endswith ( ' / ' ) :
text = text [ : - 1 ]
2013-02-14 06:51:31 +04:00
storfile [ text ] . append ( ( pagename , section ) )
if text not in formatting :
# use element as formatted display
formatting [ text ] = name
else :
text = ' ' . join ( name . itertext ( ) )
storfile [ text ] . append ( ( pagename , section ) )
formatting [ text ] = name
2013-06-27 03:48:19 +04:00
storfile = directive_groups [ ' constants ' ]
for name in t . iterfind ( ' .//constant ' ) :
if name . attrib . get ( ' noindex ' ) :
continue
name . tail = ' '
if name . text . startswith ( ' ( ' ) : # a cast, strip it
name . text = name . text . partition ( ' ' ) [ 2 ]
storfile [ name . text ] . append ( ( pagename , section ) )
formatting [ name . text ] = name
2013-01-26 20:27:35 +04:00
def _make_section ( template , name , directives , formatting ) :
2013-01-15 06:02:49 +04:00
varlist = template . find ( " .//*[@id= ' {} ' ] " . format ( name ) )
2012-08-09 20:08:14 +04:00
for varname , manpages in sorted ( directives . items ( ) ) :
entry = tree . SubElement ( varlist , ' varlistentry ' )
2013-01-26 20:27:35 +04:00
term = tree . SubElement ( entry , ' term ' )
2013-05-30 06:31:20 +04:00
display = deepcopy ( formatting [ varname ] )
term . append ( display )
2013-01-26 20:27:35 +04:00
2012-08-09 20:08:14 +04:00
para = tree . SubElement ( tree . SubElement ( entry , ' listitem ' ) , ' para ' )
b = None
2013-01-26 19:47:16 +04:00
for manpage , manvolume in sorted ( set ( manpages ) ) :
2013-05-30 06:31:20 +04:00
if b is not None :
b . tail = ' , '
b = tree . SubElement ( para , ' citerefentry ' )
c = tree . SubElement ( b , ' refentrytitle ' )
c . text = manpage
d = tree . SubElement ( b , ' manvolnum ' )
d . text = manvolume
2012-08-09 20:08:14 +04:00
entry . tail = ' \n \n '
2013-01-15 06:34:19 +04:00
def _make_colophon ( template , groups ) :
count = 0
pages = set ( )
for group in groups :
count + = len ( group )
for pagelist in group . values ( ) :
pages | = set ( pagelist )
para = template . find ( " .//para[@id= ' colophon ' ] " )
para . text = COLOPHON . format ( count = count ,
sections = len ( groups ) ,
pages = len ( pages ) )
2013-01-26 20:27:35 +04:00
def _make_page ( template , directive_groups , formatting ) :
2012-08-09 20:08:14 +04:00
""" Create an XML tree from directive_groups.
directive_groups = {
' class ' : { ' variable ' : [ ( ' manpage ' , ' manvolume ' ) , . . . ] ,
' variable2 ' : . . . } ,
. . .
}
"""
for name , directives in directive_groups . items ( ) :
2013-05-30 06:31:20 +04:00
_make_section ( template , name , directives , formatting )
2012-08-09 20:08:14 +04:00
2013-01-15 06:34:19 +04:00
_make_colophon ( template , directive_groups . values ( ) )
2013-01-15 06:02:49 +04:00
return template
2012-08-09 20:08:14 +04:00
2013-01-26 19:47:16 +04:00
def make_page ( * xml_files ) :
2012-08-09 20:08:14 +04:00
" Extract directives from xml_files and return XML index tree. "
2013-01-15 06:02:49 +04:00
template = tree . fromstring ( TEMPLATE )
names = [ vl . get ( ' id ' ) for vl in template . iterfind ( ' .//variablelist ' ) ]
2012-08-09 20:08:14 +04:00
directive_groups = { name : collections . defaultdict ( list )
2013-01-15 06:02:49 +04:00
for name in names }
2013-01-26 20:27:35 +04:00
formatting = { }
2012-08-09 20:08:14 +04:00
for page in xml_files :
2013-01-26 19:47:16 +04:00
try :
2013-01-26 20:27:35 +04:00
_extract_directives ( directive_groups , formatting , page )
2013-01-26 19:47:16 +04:00
except Exception :
raise ValueError ( " failed to process " + page )
2012-08-09 20:08:14 +04:00
2013-01-26 20:27:35 +04:00
return _make_page ( template , directive_groups , formatting )
2012-08-09 20:08:14 +04:00
if __name__ == ' __main__ ' :
2013-03-29 22:22:27 +04:00
with open ( sys . argv [ 1 ] , ' wb ' ) as f :
f . write ( xml_print ( make_page ( * sys . argv [ 2 : ] ) ) )