iupaizaio   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 145
dl 0
loc 195
rs 9.84
c 0
b 0
f 0
wmc 32

9 Functions

Rating   Name   Duplication   Size   Complexity  
A main() 0 3 1
A run_impl() 0 4 1
A output_code() 0 4 1
C run() 0 33 9
A run_paiza() 0 6 1
B make_code() 0 22 6
A parse_command_line() 0 38 1
C show_result() 0 27 10
A file_open() 0 6 2
1
#!/usr/bin/env python
2
#
3
# iupaizaio.py
4
#
5
# Copyright (C) 2015-2016, Takazumi Shirayanagi
6
# This software is released under the new BSD License,
7
# see LICENSE
8
#
9
10
import os
11
import sys
12
import re
13
import codecs
14
import paizaio
15
16
from argparse import ArgumentParser
17
from paizaio import PaizaIO
18
from iupaizaio_pp import PaizaPreprocessor
19
20
IUTEST_FUSED_SRC = os.path.join(os.path.dirname(__file__), '../../fused-src/iutest.min.hpp')
21
IUTEST_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*".*iutest\.hpp"')
22
EXPAND_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*"(.*?)"')
23
24
25
# command line option
26
def parse_command_line():
27
    parser = ArgumentParser()
28
    parser.add_argument(
29
        '-v',
30
        '--version',
31
        action='version',
32
        version=u'%(prog)s version 0.2'
33
    )
34
    parser.add_argument(
35
        '--stdin',
36
        help='set stdin.'
37
    )
38
    parser.add_argument(
39
        '-o',
40
        '--output',
41
        help='output source code.'
42
    )
43
    parser.add_argument(
44
        '--encoding',
45
        help='set encoding.'
46
    )
47
    parser.add_argument(
48
        '--expand_include',
49
        action='store_true',
50
        help='expand include file.'
51
    )
52
    parser.add_argument(
53
        '--use-main',
54
        action='store_true',
55
        help='IUTEST_USE_MAIN.'
56
    )
57
    parser.add_argument(
58
        'code',
59
        metavar='CODE',
60
        help='source code file'
61
    )
62
    options = parser.parse_args()
63
    return options
64
65
66
# file open
67
def file_open(path, mode, encoding):
68
    if encoding:
69
        file = codecs.open(path, mode, encoding)
70
    else:
71
        file = open(path, mode)
72
    return file
73
74
75
# make code
76
def make_code(path, encoding, expand):
77
    code = ''
78
    file = file_open(path, 'r', encoding)
79
    for line in file:
80
        m = IUTEST_INCLUDE_REGEX.match(line)
81
        if m:
82
            f = codecs.open(IUTEST_FUSED_SRC, 'r', 'utf-8-sig')
83
84
            code += '//========================================================>>>> ' + line
85
            code += f.read()
86
            code += '//========================================================<<<< ' + line
87
        else:
88
            if expand:
89
                m = EXPAND_INCLUDE_REGEX.match(line)
90
                if m:
91
                    include_path = os.path.join(os.path.dirname(path), m.group(1))
92
                    if os.path.exists(include_path):
93
                        code += make_code(include_path, encoding, expand)
94
                        code += '// '
95
            code += line
96
    file.close()
97
    return code
98
99
100
# run paiza
101
def run_paiza(code, options):
102
    paiza = PaizaIO()
103
    paiza.longpoll(True)
104
    paiza.longpoll_timeout(100)
105
    paiza.code(code)
106
    return paiza.run()
107
108
109
# show result
110
def show_result(r):
111
    if 'error' in r:
112
        print(r['error'])
113
        sys.exit(1)
114
    build_result = r['build_result']
115
    if 'success' in build_result:
116
        if 'stdout' in r:
117
            print('stdout:')
118
            print(r['stdout'])
119
        if 'stderr' in r:
120
            print('stderr:')
121
            print(r['stderr'])
122
        if 'time' in r:
123
            print('time:')
124
            print(r['time'])
125
        if 'memory' in r:
126
            print('memory:')
127
            print(r['memory'])
128
        if 'exit_code' in r:
129
            return int(r['exit_code'])
130
    else:
131
        if 'build_stderr' in r:
132
            print(r['build_stderr'])
133
        if 'build_exit_code' in r:
134
            return int(r['build_exit_code'])
135
136
    return 1
137
138
139
# output code
140
def output_code(path, code, encoding):
141
    f = file_open(path, 'w', encoding)
142
    f.write(code)
143
    f.close()
144
145
146
def run_impl(code, options):
147
    r = run_paiza(code, options)
148
    b = show_result(r)
149
    sys.exit(b)
150
151
152
# run
153
def run(options):
154
    filepath = options.code
155
    if not os.path.exists(filepath):
156
        sys.exit(1)
157
    code = make_code(filepath, options.encoding, options.expand_include)
158
    if options.output:
159
        output_code(options.output, code, options.encoding)
160
    try:
161
        run_impl(code, options)
162
    except paizaio.TooLongException as e:
163
        print(e)
164
        output = options.output
165
        if not options.output:
166
            output = "paizaio-toolong-sourcecode.cpp"
167
            output_code(output, code, options.encoding)
168
            print("source code -> " + output)
169
        try:
170
            pp = PaizaPreprocessor()
171
            output = os.path.basename(filepath) + ".p"
172
            macros = {}
173
            if options.use_main:
174
                macros['IUTEST_USE_MAIN'] = '1'
175
            code = pp.preprocess(code, macros)
176
            output_code("paizaio-sourcecode.cpp", code, options.encoding)
177
            run_impl(code, options)
178
        except paizaio.TooLongException as e:
179
            print(e)
180
            sys.exit(1)
181
        except Exception as e:
182
            print(e)
183
            raise
184
    except:
185
        raise
186
187
188
def main():
189
    options = parse_command_line()
190
    run(options)
191
192
193
if __name__ == '__main__':
194
    main()
195