mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-01-18 05:45:33 -07:00
🔨 Fix and improve schema.py (#28228)
This commit is contained in:
parent
c39f32c542
commit
54dfe6237c
1 changed files with 39 additions and 28 deletions
|
|
@ -61,8 +61,7 @@ def find_grouping(gdict, filekey, sectkey, optkey, pindex):
|
|||
optparts[pindex] = '*'
|
||||
wildkey = '_'.join(optparts)
|
||||
kkey = f'{filekey}|{sectkey}|{wildkey}'
|
||||
if kkey not in gdict: gdict[kkey] = []
|
||||
gdict[kkey].append((subkey, modkey))
|
||||
gdict.setdefault(kkey, []).append((subkey, modkey))
|
||||
|
||||
# Build a list of potential groups. Only those with multiple items will be grouped.
|
||||
def group_options(schema):
|
||||
|
|
@ -137,7 +136,9 @@ def extract_files(filekey):
|
|||
# Regex for #define NAME [VALUE] [COMMENT] with sanitized line
|
||||
defgrep = re.compile(r'^(//)?\s*(#define)\s+([A-Za-z0-9_]+)\s*(.*?)\s*(//.+)?$')
|
||||
# Pattern to match a float value
|
||||
flt = r'[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?'
|
||||
flt = r'[-+]?\s*(?:\d+\.|\d*\.\d+)(?:[eE][-+]?\d+)?[fF]?'
|
||||
# Pattern to match an integer expression
|
||||
int_expr = r'(?:[-+]?\s*\d+(?:\s*[*\/+\-]\s*\d+)*)'
|
||||
# Start with unknown state
|
||||
state = Parse.NORMAL
|
||||
# Serial ID
|
||||
|
|
@ -314,9 +315,11 @@ def extract_files(filekey):
|
|||
|
||||
# Parenthesize the given expression if needed
|
||||
def atomize(s):
|
||||
if s == '' \
|
||||
or re.match(r'^[A-Za-z0-9_]*(\([^)]+\))?$', s) \
|
||||
or re.match(r'^[A-Za-z0-9_]+ == \d+?$', s):
|
||||
s = s.strip()
|
||||
if not s or s.isidentifier() or (s.startswith('(') and s.endswith(')')):
|
||||
return s
|
||||
if re.match(r'^[A-Za-z0-9_]*(\([^)]+\))$', s) \
|
||||
or re.match(r'^[A-Za-z0-9_]+\s*[=!<>]=?\s*.*$', s):
|
||||
return s
|
||||
return f'({s})'
|
||||
|
||||
|
|
@ -369,27 +372,30 @@ def extract_files(filekey):
|
|||
}
|
||||
|
||||
# Type is based on the value
|
||||
value_type = \
|
||||
'switch' if val == '' \
|
||||
else 'int' if re.match(r'^[-+]?\s*\d+$', val) \
|
||||
else 'ints' if re.match(r'^([-+]?\s*\d+)(\s*,\s*[-+]?\s*\d+)+$', val) \
|
||||
else 'floats' if re.match(rf'({flt}(\s*,\s*{flt})+)', val) \
|
||||
else 'float' if re.match(f'^({flt})$', val) \
|
||||
else 'string' if val[0] == '"' \
|
||||
else 'char' if val[0] == "'" \
|
||||
else 'bool' if val in ('true', 'false') \
|
||||
else 'state' if val in ('HIGH', 'LOW') \
|
||||
else 'enum' if re.match(r'^[A-Za-z0-9_]{3,}$', val) \
|
||||
else 'int[]' if re.match(r'^{\s*[-+]?\s*\d+(\s*,\s*[-+]?\s*\d+)*\s*}$', val) \
|
||||
else 'float[]' if re.match(r'^{{\s*{flt}(\s*,\s*{flt})*\s*}}$', val) \
|
||||
else 'array' if val[0] == '{' \
|
||||
else ''
|
||||
value_type = (
|
||||
'switch' if val == ''
|
||||
else 'int' if re.match(r'^[-+]?\s*\d+$', val)
|
||||
else 'ints' if re.match(r'^[-+]?\s*\d+(?:\s*,\s*[-+]?\s*\d+)+$', val)
|
||||
else 'floats' if re.match(rf"^{flt}(?:\s*,\s*{flt})+$", val)
|
||||
else 'float' if re.match(rf"^{flt}$", val)
|
||||
else 'string' if val.startswith('"')
|
||||
else 'char' if val.startswith("'")
|
||||
else 'bool' if val in ('true', 'false')
|
||||
else 'state' if val in ('HIGH', 'LOW')
|
||||
else 'int[]' if re.match(rf"^\{{\s*{int_expr}(?:\s*,\s*{int_expr})*\s*\}}$", val)
|
||||
else 'float[]' if re.match(rf"^\{{\s*{flt}(?:\s*,\s*{flt})*\s*\}}$", val)
|
||||
else 'array' if val.startswith('{')
|
||||
else 'enum' if re.match(r'^[A-Za-z0-9_]{3,}$', val)
|
||||
else ''
|
||||
)
|
||||
|
||||
val = (val == 'true') if value_type == 'bool' \
|
||||
else int(val) if value_type == 'int' \
|
||||
else val.replace('f','') if value_type == 'floats' \
|
||||
else float(val.replace('f','')) if value_type == 'float' \
|
||||
else val
|
||||
val = (
|
||||
(val == 'true') if value_type == 'bool'
|
||||
else int(val) if value_type == 'int'
|
||||
else val.replace('f','') if value_type == 'floats'
|
||||
else float(val.replace('f','')) if value_type == 'float'
|
||||
else val
|
||||
)
|
||||
|
||||
if val != '': define_info['value'] = val
|
||||
if value_type != '': define_info['type'] = value_type
|
||||
|
|
@ -496,9 +502,14 @@ def main():
|
|||
unk = not inargs(['some','json','jsons','group','yml','yaml', '-h', '--help'])
|
||||
if (unk): print(f"Unknown option: '{args[0]}'")
|
||||
if inargs(['-h', '--help']) or unk:
|
||||
print("Extract firmware configuration into structured JSON or YAML schema format.")
|
||||
print("Usage: schema.py [-h] [some|json|jsons|group|yml|yaml]")
|
||||
print(" some = json + yml")
|
||||
print(" jsons = json + group")
|
||||
print(" some Generate both JSON and YAML output (schema.json and schema.yml)")
|
||||
print(" json Generate JSON output (schema.json)")
|
||||
print(" jsons Generate grouped JSON output with wildcard options (schema.json and schema_grouped.json)")
|
||||
print(" group Generate grouped JSON output only (schema_grouped.json)")
|
||||
print(" yml Generate YAML output (schema.yml)")
|
||||
print(" yaml Same as 'yml'")
|
||||
return
|
||||
|
||||
# JSON schema
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue