#! /usr/bin/env python
#  -*- Python -*-
#
#  This script can be used to identify undocumented modules in the Python
#  standard library.  Use it like this:
#
#  .../Doc/tools/listmodules --ignore-from .../Doc/paper-<paper>/modlib.idx

"""%(program)s - list modules in the Python standard library

-a, --annotate	  Annotate the module names with the subdirectory they
                  live in
-c, --categorize  Group the modules by subdirectory
-i <file>,

--ignore-from <file>	Ignore the modules listed in <file>.  <file> may
                  contain a list of module names or a module index file
                  as produced when formatting the Python documentation
                  (.idx or .html flavor).

If neither -a nor -c are given, the modules are listed in alphabetical
order.

Note that -a and -c are mutually exclusive.

Limitation: Modules loadable as shared objects may not be listed,
though this script attempts to locate such modules.

"""

__version__ = '$Revision$'

import getopt
import glob
import os
import re
import string
import sys


REMOVE_DIRS = ["dos-8x3", "encodings", "distutils",
               "lib-old", "lib-stdwin", "test"]


def main():
    args = sys.argv[1:]
    annotate = 0
    builtin = 0
    categorize = 0
    ignore_dict = {}
    ignore = ignore_dict.has_key
    try:
        opts, args = getopt.getopt(
            args, "abchi:",
            ["annotate", "built-in", "categorize", "help", "ignore-from="])
    except getopt.error, msg:
        sys.stdout = sys.stderr
        print msg
        print
        usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt in ("-a", "--annotate"):
            annotate = 1
        elif opt in ("-b", "--built-in"):
            builtin = 1
        elif opt in ("-c", "--categorize"):
            categorize = 1
        elif opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt in ("-i", "--ignore-from"):
            data = open(arg).read()
            if data[:1] == "\\":
                ignore_from_idx(data, ignore_dict)
            else:
                ignore_from_modulelist(data, ignore_dict)
    if args or (annotate and categorize):
        usage()
        sys.exit(2)
    #
    # Populate the database:
    #
    srcdir = os.path.normpath(os.path.join(
        os.path.dirname(sys.argv[0]), os.pardir, os.pardir))
    os.chdir(srcdir)
    modules_by_name = {}
    modules_by_dir = {}
    if builtin:
        l = []
        modules_by_dir["<builtin>"] = l
        for name in sys.builtin_module_names:
            if not ignore(name):
                modules_by_name[name] = "<built-in>"
                l.append(name)
    rx = re.compile("Lib/plat-[a-zA-Z0-9]*/")
    fp = os.popen("find Lib -name \*.py -print", "r")
    while 1:
        line = fp.readline()
        if not line:
            break
        m = rx.match(line)
        if m:
            line = "Lib/plat-*/" + line[m.end():]
        line = line[4:-4]                # strip off 'Lib/' and '.py\n'
        dir, name = os.path.split(line)
        dir = dir or "<standard>"
        if ignore(name):
            continue
        if dir not in REMOVE_DIRS:
            modules_by_name[name] = dir
            l = modules_by_dir.get(dir, [])
            modules_by_dir[dir] = l
            if name not in l:
                l.append(name)
    # load up extension modules:
    pwd = os.getcwd()
    try:
        os.chdir("Modules")
        dir = "<extension>"
        for line in glob.glob("*module.c"):
            name = line[:-8]
            if ignore(name) or modules_by_name.has_key(name) or name == "xx":
                continue
            modules_by_name[name] = dir
            l = modules_by_dir.get(dir, [])
            modules_by_dir[dir] = l
            if name not in l:
                l.append(name)
    finally:
        os.chdir(pwd)
    #
    # Dump the results:
    #
    if annotate:
        modules = modules_by_name.items()
        modules.sort()
        width = max(map(len, modules_by_name.keys()))
        format = "%%-%ds  %%s" % width
        for name, dir in modules:
            if dir and dir[0] != "<":
                print format % (name, dir)
            else:
                print name
    elif categorize:
        modules = modules_by_dir.items()
        modules.sort()
        width = max(map(len, modules_by_dir.keys()))
        format = "%%-%ds  %%s" % width
        for dir, names in modules:
            names.sort()
            print format % (dir, names[0])
            for name in names[1:]:
                print format % ('', name)
            print
    else:
        modules = modules_by_name.keys()
        modules.sort()
        print string.join(modules, "\n")


def ignore_from_modulelist(data, ignore_dict):
    for name in string.split(data):
        ignore_dict[name] = name

def ignore_from_idx(data, ignore_dict):
    data = string.replace(data, r"\hackscore  {}", "_")
    rx = re.compile(r"\\indexentry\s*{([^@]*)@")
    for line in string.split(data, "\n"):
        m = rx.match(line)
        if m:
            name = m.group(1)
            ignore_dict[name] = name


def usage():
    vars = {}
    vars["program"] = os.path.basename(sys.argv[0])
    print __doc__ % vars


if __name__ == "__main__":
    main()
