summaryrefslogtreecommitdiffstats
path: root/xdd2esi.py
blob: b522f9aaecdc21212999202a4bcd3186ae601d58 (plain)
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
#!/usr/bin/python
# vim: set fileencoding=utf-8 tabstop=8 expandtab shiftwidth=4 softtabstop=4 :

""" xdd2esi.py
User interface for xdd2esilib.py
30. May 2012
"""

import xdd2esilib
import logging
import argparse
import warnings

__version__ = 2.1
_versioninfo = "xdd2esi v{}".format(__version__)

def parseargs():
    """ Parse the command-line arguments """
    parser = argparse.ArgumentParser(
        description='Convert XDD files to ESI files',
        epilog='Florian Bruhin')
    # Positional
    parser.add_argument('infile', default=None, help='Input file')
    parser.add_argument(
        'outfile', default=None,
        help='Output file (-: stdout)')
    parser.add_argument(
        '-v', '--version', help='Show the version of this script',
        action='version', version="%(prog)s {}".format(__version__))
    # Conversion
    convertopts = parser.add_argument_group("Conversion options")
    convertopts.add_argument(
        '-s', '--shift', default=None, nargs=3,
        metavar=('start_range', 'end_range', 'offset'), action='append',
        help="Shift IDs <startrange> to <endrange> by <offset> (may be used "
        "multiple times)", type=opt_hexint)
    convertopts.add_argument(
        '-t', '--template', metavar='template_file', action='store',
        help="Replace <Dictionary>-Tree in template-file")
    convertopts.add_argument(
        '-f', '--force', help="Don't treat warnings as errors",
        action='store_true')
    convertopts.add_argument(
        '-S', '--schema', metavar='xml_schema', action='store',
        help="Verify output with an xml-schema")
    # --ugly and --nobasic store inverted values
    convertopts.add_argument(
        '-u', '--ugly', help="Don't pretty-print", action='store_false',
        default=True, dest='pretty')
    convertopts.add_argument(
        '-n', '--nobasic', help="Don't add basic data types",
        action='store_false', default=True, dest='addbasic')
    # Debug
    debugopts = parser.add_argument_group("Debugging options")
    debugopts.add_argument(
        '-d', '--dump', help="Dump objects after reading XDD",
        action='store_true', default=False)
    debugopts.add_argument(
        '-D', '--dry-run', help="Don't actually convert, only check input "
        "file for errors", action='store_true', default=False, dest='dryrun')
    debugopts.add_argument(
        '-l', '--loglevel', default='info', type=opt_loglevel)
    options = parser.parse_args()
    return options

def opt_loglevel(loglevel):
    """ Get the numeric loglevel from the command line option """
    numeric_level = getattr(logging, loglevel.upper(), None)
    if not isinstance(numeric_level, int):
        raise argparse.ArgumentTypeError('{} is not a valid '
            'loglevel!'.format(loglevel))
    return numeric_level

def opt_hexint(num):
    """ Takes hexints for argparse and returns dec-integers """
    try:
        newnum = int(num, 16)
    except ValueError:
        raise argparse.ArgumentTypeError
    return newnum

def custom_formatwarning(message, category, filename, lineno, file_=None,
                         line=None):
    """ Warning-format for warnings """
    retval = str(message)
    return retval
    
def initlog(numeric_level):
    """ Initialize logging """
    if numeric_level == logging.DEBUG:
        logformat = ("[%(levelname)s] [%(filename)s:%(funcName)s():"
                     "%(lineno)d] %(message)s")
    else:
        logformat = "%(levelname)8s %(module)10s  %(message)s"
    logging.basicConfig(level=numeric_level, format=logformat)
    logging.captureWarnings(True)

def init():
    """ Generic initializing """
    options = parseargs()
    initlog(options.loglevel)
    warnings.formatwarning = custom_formatwarning
    return options

def main():
    """ Main function """
    opt = init()
    if opt.force:
        warnings.simplefilter("default")
    else:
        warnings.simplefilter("error")
    if opt.dryrun:
        outfile = None
    else:
        outfile = opt.outfile
    xdd2esilib.run(opt.infile, outfile, opt.dump, opt.pretty, opt.shift,
                   opt.addbasic, opt.template, opt.schema, _versioninfo)

if __name__ == '__main__':
    main()