Skip to content

Commit 4f5ebb8

Browse files
authored
Refactor extraction-scripts to reduce code-duplication (#2592)
extract_configs.py now supports reading min, max or default values from a #define value (which reduces false-positives)
1 parent de5fb4f commit 4f5ebb8

File tree

3 files changed

+219
-178
lines changed

3 files changed

+219
-178
lines changed

tools/extract_build_defines.py

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,17 @@ def __init__(self, message, errors):
4646

4747
BUILD_DEFINE_RE = re.compile(r'#\s+{}:\s+(\w+),\s+([^,]+)(?:,\s+(.*))?$'.format(BASE_BUILD_DEFINE_NAME))
4848

49-
ALLOWED_CONFIG_PROPERTIES = set(['type', 'default', 'min', 'max', 'group'])
49+
PROPERTY_TYPE = 'type'
50+
PROPERTY_DEFAULT = 'default'
51+
PROPERTY_MIN = 'min'
52+
PROPERTY_MAX = 'max'
53+
PROPERTY_GROUP = 'group'
54+
ALLOWED_CONFIG_PROPERTIES = set([PROPERTY_TYPE, PROPERTY_DEFAULT, PROPERTY_MIN, PROPERTY_MAX, PROPERTY_GROUP])
55+
56+
PROPERTY_TYPE_INT = 'int'
57+
PROPERTY_TYPE_BOOL = 'bool'
58+
PROPERTY_TYPE_STRING = 'string'
59+
PROPERTY_TYPE_LIST = 'list'
5060

5161
CHIP_NAMES = ["rp2040", "rp2350"]
5262

@@ -57,72 +67,64 @@ def __init__(self, message, errors):
5767

5868

5969
def ValidateAttrs(config_name, config_attrs, file_path, linenum):
60-
_type = config_attrs.get('type')
70+
type_str = config_attrs.get(PROPERTY_TYPE)
6171
errors = []
6272

6373
# Validate attrs
6474
for key in config_attrs.keys():
6575
if key not in ALLOWED_CONFIG_PROPERTIES:
6676
errors.append(Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key)))
6777

68-
if _type == 'int':
69-
_min = _max = _default = None
70-
if config_attrs.get('min', None) is not None:
71-
value = config_attrs['min']
72-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
73-
if m:
74-
_min = int(m.group(1)) * 10**int(m.group(2))
75-
else:
76-
_min = int(value, 0)
77-
if config_attrs.get('max', None) is not None:
78-
value = config_attrs['max']
79-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
80-
if m:
81-
_max = int(m.group(1)) * 10**int(m.group(2))
82-
else:
83-
_max = int(value, 0)
84-
if config_attrs.get('default', None) is not None:
85-
if '/' not in config_attrs['default']:
78+
str_values = dict()
79+
parsed_values = dict()
80+
if type_str == PROPERTY_TYPE_INT:
81+
for attr_name in (PROPERTY_MIN, PROPERTY_MAX, PROPERTY_DEFAULT):
82+
str_values[attr_name] = config_attrs.get(attr_name, None)
83+
if str_values[attr_name] is not None:
8684
try:
87-
value = config_attrs['default']
88-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
85+
m = re.match(r'^(\d+)e(\d+)$', str_values[attr_name].lower())
8986
if m:
90-
_default = int(m.group(1)) * 10**int(m.group(2))
87+
parsed_values[attr_name] = int(m.group(1)) * 10**int(m.group(2))
9188
else:
92-
_default = int(value, 0)
89+
parsed_values[attr_name] = int(str_values[attr_name], 0)
9390
except ValueError:
94-
pass
95-
if _min is not None and _max is not None:
96-
if _min > _max:
97-
errors.append(Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max'])))
98-
if _min is not None and _default is not None:
99-
if _min > _default:
100-
errors.append(Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default'])))
101-
if _default is not None and _max is not None:
102-
if _default > _max:
103-
errors.append(Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max'])))
104-
elif _type == 'bool':
105-
assert 'min' not in config_attrs
106-
assert 'max' not in config_attrs
107-
_default = config_attrs.get('default', None)
108-
if _default is not None:
109-
if '/' not in _default:
110-
if (_default not in ('0', '1')) and (_default not in all_config_names):
111-
logger.info('{} at {}:{} has non-integer default value "{}"'.format(config_name, file_path, linenum, config_attrs['default']))
112-
113-
elif _type == 'string':
114-
assert 'min' not in config_attrs
115-
assert 'max' not in config_attrs
116-
_default = config_attrs.get('default', None)
117-
elif _type == 'list':
118-
assert 'min' not in config_attrs
119-
assert 'max' not in config_attrs
120-
_default = config_attrs.get('default', None)
91+
logger.info('{} at {}:{} has non-integer {} value "{}"'.format(config_name, file_path, linenum, attr_name, str_values[attr_name]))
92+
for (small_attr, large_attr) in (
93+
(PROPERTY_MIN, PROPERTY_MAX),
94+
(PROPERTY_MIN, PROPERTY_DEFAULT),
95+
(PROPERTY_DEFAULT, PROPERTY_MAX),
96+
):
97+
if small_attr in parsed_values and large_attr in parsed_values and parsed_values[small_attr] > parsed_values[large_attr]:
98+
errors.append(Exception('{} at {}:{} has {} {} > {} {}'.format(config_name, file_path, linenum, small_attr, str_values[small_attr], large_attr, str_values[large_attr])))
99+
100+
elif type_str == PROPERTY_TYPE_BOOL:
101+
assert PROPERTY_MIN not in config_attrs
102+
assert PROPERTY_MAX not in config_attrs
103+
104+
attr_name = PROPERTY_DEFAULT
105+
str_values[attr_name] = config_attrs.get(attr_name, None)
106+
if str_values[attr_name] is not None:
107+
if (str_values[attr_name] not in ('0', '1')) and (str_values[attr_name] not in all_config_names):
108+
logger.info('{} at {}:{} has non-integer {} value "{}"'.format(config_name, file_path, linenum, attr_name, str_values[attr_name]))
109+
110+
elif type_str == PROPERTY_TYPE_STRING:
111+
assert PROPERTY_MIN not in config_attrs
112+
assert PROPERTY_MAX not in config_attrs
113+
114+
attr_name = PROPERTY_DEFAULT
115+
str_values[attr_name] = config_attrs.get(attr_name, None)
116+
117+
elif type_str == PROPERTY_TYPE_LIST:
118+
assert PROPERTY_MIN not in config_attrs
119+
assert PROPERTY_MAX not in config_attrs
120+
121+
attr_name = PROPERTY_DEFAULT
122+
str_values[attr_name] = config_attrs.get(attr_name, None)
123+
121124
else:
122-
errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_BUILD_DEFINE_NAME, _type, file_path, linenum)))
123-
124-
return errors
125+
errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_BUILD_DEFINE_NAME, type_str, file_path, linenum)))
125126

127+
return errors
126128

127129
errors = []
128130

tools/extract_cmake_configs.py

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# Script to scan the Raspberry Pi Pico SDK tree searching for CMake configuration items
99
# Outputs a tab separated file of the configuration item:
10-
# name location platform chip description type advanced default docref group
10+
# name location platform chip description type advanced default docref group max
1111
#
1212
# Usage:
1313
#
@@ -46,7 +46,19 @@ def __init__(self, message, errors):
4646

4747
CMAKE_CONFIG_RE = re.compile(r'#\s+{}:\s+(\w+),\s+([^,]+)(?:,\s+(.*))?$'.format(BASE_CMAKE_CONFIG_NAME))
4848

49-
ALLOWED_CONFIG_PROPERTIES = set(['type', 'default', 'min', 'max', 'group', 'advanced', 'docref'])
49+
PROPERTY_TYPE = 'type'
50+
PROPERTY_DEFAULT = 'default'
51+
PROPERTY_MIN = 'min'
52+
PROPERTY_MAX = 'max'
53+
PROPERTY_GROUP = 'group'
54+
PROPERTY_ADVANCED = 'advanced'
55+
PROPERTY_DOCREF = 'docref'
56+
ALLOWED_CONFIG_PROPERTIES = set([PROPERTY_TYPE, PROPERTY_DEFAULT, PROPERTY_MIN, PROPERTY_MAX, PROPERTY_GROUP, PROPERTY_ADVANCED, PROPERTY_DOCREF])
57+
58+
PROPERTY_TYPE_INT = 'int'
59+
PROPERTY_TYPE_BOOL = 'bool'
60+
PROPERTY_TYPE_STRING = 'string'
61+
PROPERTY_TYPE_LIST = 'list'
5062

5163
CHIP_NAMES = ["rp2040", "rp2350"]
5264

@@ -57,69 +69,63 @@ def __init__(self, message, errors):
5769

5870

5971
def ValidateAttrs(config_name, config_attrs, file_path, linenum):
60-
_type = config_attrs.get('type')
72+
type_str = config_attrs.get(PROPERTY_TYPE)
6173
errors = []
6274

6375
# Validate attrs
6476
for key in config_attrs.keys():
6577
if key not in ALLOWED_CONFIG_PROPERTIES:
6678
errors.append(Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key)))
6779

68-
if _type == 'int':
69-
_min = _max = _default = None
70-
if config_attrs.get('min', None) is not None:
71-
value = config_attrs['min']
72-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
73-
if m:
74-
_min = int(m.group(1)) * 10**int(m.group(2))
75-
else:
76-
_min = int(value, 0)
77-
if config_attrs.get('max', None) is not None:
78-
value = config_attrs['max']
79-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
80-
if m:
81-
_max = int(m.group(1)) * 10**int(m.group(2))
82-
else:
83-
_max = int(value, 0)
84-
if config_attrs.get('default', None) is not None:
85-
if '/' not in config_attrs['default']:
80+
str_values = dict()
81+
parsed_values = dict()
82+
if type_str == PROPERTY_TYPE_INT:
83+
for attr_name in (PROPERTY_MIN, PROPERTY_MAX, PROPERTY_DEFAULT):
84+
str_values[attr_name] = config_attrs.get(attr_name, None)
85+
if str_values[attr_name] is not None:
8686
try:
87-
value = config_attrs['default']
88-
m = re.match(r'^(\d+)e(\d+)$', value.lower())
87+
m = re.match(r'^(\d+)e(\d+)$', str_values[attr_name].lower())
8988
if m:
90-
_default = int(m.group(1)) * 10**int(m.group(2))
89+
parsed_values[attr_name] = int(m.group(1)) * 10**int(m.group(2))
9190
else:
92-
_default = int(value, 0)
91+
parsed_values[attr_name] = int(str_values[attr_name], 0)
9392
except ValueError:
94-
pass
95-
if _min is not None and _max is not None:
96-
if _min > _max:
97-
errors.append(Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max'])))
98-
if _min is not None and _default is not None:
99-
if _min > _default:
100-
errors.append(Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default'])))
101-
if _default is not None and _max is not None:
102-
if _default > _max:
103-
errors.append(Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max'])))
104-
elif _type == 'bool':
105-
assert 'min' not in config_attrs
106-
assert 'max' not in config_attrs
107-
_default = config_attrs.get('default', None)
108-
if _default is not None:
109-
if '/' not in _default:
110-
if (_default not in ('0', '1')) and (_default not in all_config_names):
111-
logger.info('{} at {}:{} has non-integer default value "{}"'.format(config_name, file_path, linenum, config_attrs['default']))
112-
113-
elif _type == 'string':
114-
assert 'min' not in config_attrs
115-
assert 'max' not in config_attrs
116-
_default = config_attrs.get('default', None)
117-
elif _type == 'list':
118-
assert 'min' not in config_attrs
119-
assert 'max' not in config_attrs
120-
_default = config_attrs.get('default', None)
93+
# pass
94+
logger.info('{} at {}:{} has non-integer {} value "{}"'.format(config_name, file_path, linenum, attr_name, str_values[attr_name]))
95+
for (small_attr, large_attr) in (
96+
(PROPERTY_MIN, PROPERTY_MAX),
97+
(PROPERTY_MIN, PROPERTY_DEFAULT),
98+
(PROPERTY_DEFAULT, PROPERTY_MAX),
99+
):
100+
if small_attr in parsed_values and large_attr in parsed_values and parsed_values[small_attr] > parsed_values[large_attr]:
101+
errors.append(Exception('{} at {}:{} has {} {} > {} {}'.format(config_name, file_path, linenum, small_attr, str_values[small_attr], large_attr, str_values[large_attr])))
102+
103+
elif type_str == PROPERTY_TYPE_BOOL:
104+
assert PROPERTY_MIN not in config_attrs
105+
assert PROPERTY_MAX not in config_attrs
106+
107+
attr_name = PROPERTY_DEFAULT
108+
str_values[attr_name] = config_attrs.get(attr_name, None)
109+
if str_values[attr_name] is not None:
110+
if (str_values[attr_name] not in ('0', '1')) and (str_values[attr_name] not in all_config_names):
111+
logger.info('{} at {}:{} has non-integer {} value "{}"'.format(config_name, file_path, linenum, attr_name, str_values[attr_name]))
112+
113+
elif type_str == PROPERTY_TYPE_STRING:
114+
assert PROPERTY_MIN not in config_attrs
115+
assert PROPERTY_MAX not in config_attrs
116+
117+
attr_name = PROPERTY_DEFAULT
118+
str_values[attr_name] = config_attrs.get(attr_name, None)
119+
120+
elif type_str == PROPERTY_TYPE_LIST:
121+
assert PROPERTY_MIN not in config_attrs
122+
assert PROPERTY_MAX not in config_attrs
123+
124+
attr_name = PROPERTY_DEFAULT
125+
str_values[attr_name] = config_attrs.get(attr_name, None)
126+
121127
else:
122-
errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_CMAKE_CONFIG_NAME, _type, file_path, linenum)))
128+
errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_CMAKE_CONFIG_NAME, type_str, file_path, linenum)))
123129

124130
return errors
125131

0 commit comments

Comments
 (0)