-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpquery.py
executable file
·64 lines (49 loc) · 1.67 KB
/
cpquery.py
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
#!/usr/bin/env python3
import sys
import argparse
from cp import CPFile
def is_integer_string(s):
return any(i.isdigit() for i in s)
def is_condition_match(table, line_no, field, condition):
if is_integer_string(condition):
return line_no + 1 == int(condition)
else:
# nothing more supported at the moment
return False
parser = argparse.ArgumentParser(
description='select values from a CP file')
parser.add_argument('expr', nargs=1,
help='xpath-like select expression')
parser.add_argument('inputs', nargs='*', help='input files')
args = parser.parse_args(sys.argv[1:])
if len(args.inputs) == 0:
args.inputs.append(sys.stdin)
select_path = args.expr[0].strip('/')
components = select_path.split('/')
if len(components) != 2:
raise ValueError('Path must contain two components.')
table_name, field_component = components
# extract condition, if any
condition = None
cond_start = field_component.find('[')
if cond_start != -1:
cond_end = field_component.find(']', cond_start)
if cond_end == -1:
raise ValueError('Undelimited condition in select path')
condition = field_component[cond_start + 1:cond_end]
field = field_component[:cond_start]
else:
field = field_component
# convert field to integer
if is_integer_string(field):
field = int(field)
for f in args.inputs:
cp = CPFile(f)
table = cp.get_table(table_name)
if table is None:
continue
for line_no in range(len(table.lines)):
if condition is None or is_condition_match(
table, line_no, field, condition):
value = table.get_field(line_no, field)
print(value)