""" If this file is used as a stand-alone program, it takes two arguments. The first argument, which is required, is either 'dec' or 'hex' (without the quotes). The second, optional, argument is a file name. If the second argument is missing, the file name defaults to "ascii.dec" or "ascii.hex" respectively.
"""
import string, sys

# Writes an ASCII code table in base 10 or 16.
def table(file, hexbit):
    if hexbit == 0:
        head = 'Dec'
        cntl_entry_format = '%3i   %3s  ^%-1s %-12s '
        space_entry_format = '%3i  SP   ' 
        printing_entry_format = '%3i  %2s   '
    else:
        head = 'Hex'
        cntl_entry_format = '%3X   %3s  ^%-1s %-12s '
        space_entry_format = '%3X  SP   ' 
        printing_entry_format = '%3X  %2s   '

    topline = \
     ' %s Name Ctrl              %s Name   %s Name   %s Name\n\n' % \
           (head, head, head, head)

    endline = \
Line ending conventions from Reference, 2.1.2: "On Unix, this [how lines are terminated] is the ASCII LF (linefeed) character. On DOS/Windows, it is the ASCII sequence CR LF (return followed by linefeed). On Macintosh, it is the ASCII CR (return) character."
    ascii = ['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL',
     'BS', 'HT', 'LF', 'VT', 'NP', 'CR', 'SO', 'SI',
     'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB',
     'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US',
     'SP', '!', '"', '#', '$', '%', '&', '\'',
     '(', ')', '*', '+', ',', '-', '.', '/',
     '0', '1', '2', '3', '4', '5', '6', '7',
     '8', '9', ':', ';', '<', '=', '>', '?',
     '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
     'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
     'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
     'X', 'Y', 'Z', '[', '\\', ']','^', '_',
     '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
     'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
     'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
     'x', 'y', 'z', '{', '|', '}', '~', 'DEL']

    # Some entries have a short comment.
    specials = { 7:'beep', 8:'backspace', 9:'tab', 10:'linefeed', \
                11:'vertical tab', 13:'return', 17:'XON', 18:'XOFF', \
                27:'escape'}
    for i in range(32):
        if not specials.has_key(i):
            specials[i] = ''

    entries = []

    # The 32 control characters.
    for i in range(32):
        entries.append(cntl_entry_format % \
              (i, ascii[i], chr(i+64), specials[i]) )

    # Space.
    entries.append(space_entry_format % 32)

    # The printing characters.
    for i in range(33, 128):
        entries.append(printing_entry_format % (i, ascii[i]) )

    # Arrange in four columns.
    lines = []
    for i in range(32):
        lines.append('%s|%s|%s|%s\n' % (\
             entries[i], entries[32+i], entries[64+i], entries[96+i]) )

    text = string.join(lines, '')

    f = open(file, 'w')
    f.write(topline)
    f.write(text)
    f.write(endline)
    f.close()
    
if __name__ == '__main__':
    if len(sys.argv) > 2:
        raise Exception, 'Too many arguments.'

    if sys.argv[1] == 'dec':
        if len(sys.argv) == 2:
            file = 'ascii.dec'
        else:
            file = sys.argv[2]
        table(file, 0)

    elif sys.argv[1] == 'hex':
        if len(sys.argv) == 2:
            file = 'ascii.hex'
        else:
            file = sys.argv[2]
        table(file, 1)

    else:
        raise Exception, "first argument must be 'dec' or 'hex'"