This file is indexed.

/usr/share/pyshared/cliapp/genman.py is in python-cliapp 0.23-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright (C) 2011  Lars Wirzenius
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program 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 General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


import optparse
import re


class ManpageGenerator(object):

    '''Fill in a manual page template from an OptionParser instance.'''
    
    def __init__(self, template, parser, arg_synopsis, cmd_synopsis):
        self.template = template
        self.parser = parser
        self.arg_synopsis = arg_synopsis
        self.cmd_synopsis = cmd_synopsis
        
    @property
    def options(self):
        return sorted(self.parser.option_list,
                      key=lambda o: (o._long_opts + o._short_opts)[0])
                      
    def format_template(self):
        sections = (('SYNOPSIS', self.format_synopsis()),
                    ('OPTIONS', self.format_options()))
        text = self.template
        for section, contents in sections:
            pattern = '\n.SH %s\n' % section
            text = text.replace(pattern, pattern + contents)
        return text
                      
    def format_synopsis(self):
        lines = []
        lines += ['.nh']
        lines += ['.B %s' % self.esc_dashes(self.parser.prog)]
        
        for option in self.options:
            for spec in self.format_option_for_synopsis(option):
                lines += ['.RB [ %s ]' % spec]

        if self.cmd_synopsis:
            lines += ['.PP']
            for cmd in self.cmd_synopsis:
                lines += ['.br',
                          '.B %s' % self.esc_dashes(self.parser.prog),
                          '.RI [ options ]',
                          self.esc_dashes(cmd)]
                lines += self.format_argspec(self.cmd_synopsis[cmd])
        elif self.arg_synopsis:
            lines += self.format_argspec(self.arg_synopsis)

        lines += ['.hy']
        return ''.join('%s\n' % line for line in lines)
                      
    def format_option_for_synopsis(self, option):
        if option.metavar:
            suffix = '\\fR=\\fI%s' % self.esc_dashes(option.metavar)
        else:
            suffix = ''
        for name in option._short_opts + option._long_opts:
            yield '%s%s' % (self.esc_dashes(name), suffix)

    def format_options(self):
        return ''.join(self.format_option_for_options(option)
                       for option in self.options)

    def format_option_for_options(self, option):
        lines = []
        lines += ['.TP']
        shorts = [self.esc_dashes(x) for x in option._short_opts]
        if option.metavar:
            longs = ['%s =\\fI%s' % (self.esc_dashes(x), option.metavar)
                     for x in option._long_opts]
        else:
            longs = ['%s' % self.esc_dashes(x)
                     for x in option._long_opts]
        lines += ['.BR ' + ' ", " '.join(shorts + longs)]
        lines += [self.esc_dots(self.expand_default(option).strip())]
        return ''.join('%s\n' % line for line in lines)
        
    def expand_default(self, option):
        default = self.parser.defaults.get(option.dest)
        if default is optparse.NO_DEFAULT or default is None:
            default = 'none'
        else:
            default = str(default)
        return option.help.replace('%default', default)
        
    def esc_dashes(self, optname):
        return '\\-'.join(optname.split('-'))
    
    def esc_dots(self, line):
        if line.startswith('.'):
            return '\\' + line
        else:
            return line
            
    def format_argspec(self, argspec):
        roman = re.compile(r'[^A-Z]+')
        italic = re.compile(r'[A-Z]+')
        words = ['.RI']
        while argspec:
            m = roman.match(argspec)
            if m:
                words += [self.esc_dashes(m.group(0))]
                argspec = argspec[m.end():]
            else:
                words += ['""']
            m = italic.match(argspec)
            if m:
                words += [self.esc_dashes(m.group(0))]
                argspec = argspec[m.end():]
            else:
                words += ['""']
        return [' '.join(words)]