dts: gen_defines.py: Convert to use f-strings

Use f-strings instead of .format() to makes all the macro identifier and
multiline comment building easier to read.

f-strings were added in Python 3.6, which is required by Zephyr now.

Convert some

    ... + "_" + ...

string building to f-strings as well.

f-strings are a bit faster too (because they avoid format()/str()
lookups), though it's not likely to be noticeable here.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
This commit is contained in:
Ulf Magnusson 2020-01-24 05:15:33 +01:00 committed by Anas Nashif
parent cd28b0b6d2
commit 08484d0ac4

View file

@ -35,7 +35,7 @@ def main():
try:
edt = edtlib.EDT(args.dts, args.bindings_dirs)
except edtlib.EDTError as e:
sys.exit("devicetree error: " + str(e))
sys.exit(f"devicetree error: {e}")
conf_file = open(args.conf_out, "w", encoding="utf-8")
header_file = open(args.header_out, "w", encoding="utf-8")
@ -65,7 +65,7 @@ def main():
out_comment("Active compatibles (mentioned in DTS + binding found)")
for compat in sorted(active_compats):
#define DT_COMPAT_<COMPAT> 1
out("COMPAT_{}".format(str2ident(compat)), 1)
out(f"COMPAT_{str2ident(compat)}", 1)
# Derived from /chosen
write_addr_size(edt, "zephyr,ccm", "CCM")
@ -99,23 +99,23 @@ def write_top_comment(edt):
# Writes an overview comment with misc. info at the top of the header and
# configuration file
s = """\
s = f"""\
Generated by gen_defines.py
DTS input file:
{}
{edt.dts_path}
Directories with bindings:
{}
{", ".join(map(relativize, edt.bindings_dirs))}
Nodes in dependency order (ordinal and path):
""".format(edt.dts_path, ", ".join(map(relativize, edt.bindings_dirs)))
"""
for scc in edt.scc_order():
if len(scc) > 1:
err("cycle in devicetree involving "
+ ", ".join(node.path for node in scc))
s += " {0.dep_ordinal:<3} {0.path}\n".format(scc[0])
s += f" {scc[0].dep_ordinal:<3} {scc[0].path}\n"
out_comment(s, blank_before=False)
@ -123,26 +123,25 @@ Nodes in dependency order (ordinal and path):
def write_node_comment(node):
# Writes a comment describing 'node' to the header and configuration file
s = """\
s = f"""\
Devicetree node:
{}
{node.path}
Binding (compatible = {}):
{}
Binding (compatible = {node.matching_compat}):
{relativize(node.binding_path)}
Dependency Ordinal: {}
""".format(node.path, node.matching_compat, relativize(node.binding_path),
node.dep_ordinal)
Dependency Ordinal: {node.dep_ordinal}
"""
if node.depends_on:
s += "\nRequires:\n"
for dep in node.depends_on:
s += " {:<3} {}\n".format(dep.dep_ordinal, dep.path)
s += f" {dep.dep_ordinal:<3} {dep.path}\n"
if node.required_by:
s += "\nSupports:\n"
for req in node.required_by:
s += " {:<3} {}\n".format(req.dep_ordinal, req.path)
s += f" {req.dep_ordinal:<3} {req.path}\n"
# Indent description by two spaces
s += "\nDescription:\n" + \
@ -174,13 +173,13 @@ def write_regs(node):
# Drop '_0' from the identifier if there's a single register, for
# backwards compatibility
if len(reg.node.regs) > 1:
ident = "{}_{}".format(base_ident, reg.node.regs.index(reg))
ident = f"{base_ident}_{reg.node.regs.index(reg)}"
else:
ident = base_ident
out_node(node, ident, val,
# Name alias from 'reg-names = ...'
str2ident(reg.name) + "_" + base_ident if reg.name else None)
f"{str2ident(reg.name)}_{base_ident}" if reg.name else None)
for reg in node.regs:
write_reg(reg, "BASE_ADDRESS", hex(reg.addr))
@ -209,14 +208,14 @@ def write_props(node):
out_node(node, ident, prop.val)
elif prop.type == "array":
for i, val in enumerate(prop.val):
out_node(node, "{}_{}".format(ident, i), val)
out_node(node, f"{ident}_{i}", val)
out_node_init(node, ident, prop.val)
elif prop.type == "string-array":
for i, val in enumerate(prop.val):
out_node_s(node, "{}_{}".format(ident, i), val)
out_node_s(node, f"{ident}_{i}", val)
elif prop.type == "uint8-array":
out_node_init(node, ident,
["0x{:02x}".format(b) for b in prop.val])
[f"0x{b:02x}" for b in prop.val])
else: # prop.type == "phandle-array"
write_phandle_val_list(prop)
@ -260,14 +259,14 @@ def write_bus(node):
return
if node.bus_node.label is None:
err("missing 'label' property on bus node {!r}".format(node.bus_node))
err(f"missing 'label' property on bus node {node.bus_node!r}")
# #define DT_<DEV-IDENT>_BUS_NAME <BUS-LABEL>
out_node_s(node, "BUS_NAME", str2ident(node.bus_node.label))
for compat in node.compats:
# #define DT_<COMPAT>_BUS_<BUS-TYPE> 1
out("{}_BUS_{}".format(str2ident(compat), str2ident(node.on_bus)), 1)
out(f"{str2ident(compat)}_BUS_{str2ident(node.on_bus)}", 1)
def write_existence_flags(node):
@ -278,8 +277,7 @@ def write_existence_flags(node):
# These are flags for which devices exist.
for compat in node.compats:
out("INST_{}_{}".format(node.instance_no[compat],
str2ident(compat)), 1)
out(f"INST_{node.instance_no[compat]}_{str2ident(compat)}", 1)
def node_ident(node):
@ -294,15 +292,15 @@ def node_ident(node):
ident += "{}_{:X}_".format(
str2ident(node.bus_node.matching_compat), node.bus_node.unit_addr)
ident += "{}_".format(str2ident(node.matching_compat))
ident += f"{str2ident(node.matching_compat)}_"
if node.unit_addr is not None:
ident += "{:X}".format(node.unit_addr)
ident += f"{node.unit_addr:X}"
elif node.parent.unit_addr is not None:
ident += "{:X}_{}".format(node.parent.unit_addr, str2ident(node.name))
ident += f"{node.parent.unit_addr:X}_{str2ident(node.name)}"
else:
# This is a bit of a hack
ident += "{}".format(str2ident(node.name))
ident += str2ident(node.name)
return ident
@ -324,9 +322,9 @@ def node_path_aliases(node):
aliases = []
for alias in node.aliases:
aliases.append("ALIAS_{}".format(str2ident(alias)))
aliases.append(f"ALIAS_{str2ident(alias)}")
# TODO: See if we can remove or deprecate this form
aliases.append("{}_{}".format(compat_s, str2ident(alias)))
aliases.append(f"{compat_s}_{str2ident(alias)}")
return aliases
@ -339,7 +337,7 @@ def node_instance_aliases(node):
# This is a list since a node can have multiple 'compatible' strings, each
# with their own instance number.
return ["INST_{}_{}".format(node.instance_no[compat], str2ident(compat))
return [f"INST_{node.instance_no[compat]}_{str2ident(compat)}"
for compat in node.compats]
@ -352,12 +350,12 @@ def write_addr_size(edt, prop_name, prefix):
return
if not node.regs:
err("missing 'reg' property in node pointed at by /chosen/{} ({!r})"
.format(prop_name, node))
err("missing 'reg' property in node pointed at by "
f"/chosen/{prop_name} ({node!r})")
out_comment("/chosen/{} ({})".format(prop_name, node.path))
out("{}_BASE_ADDRESS".format(prefix), hex(node.regs[0].addr))
out("{}_SIZE".format(prefix), node.regs[0].size//1024)
out_comment(f"/chosen/{prop_name} ({node.path})")
out(f"{prefix}_BASE_ADDRESS", hex(node.regs[0].addr))
out(f"{prefix}_SIZE", node.regs[0].size//1024)
def write_flash(edt):
@ -383,8 +381,7 @@ def write_flash_node(edt):
node = edt.chosen_node("zephyr,flash")
out_comment("/chosen/zephyr,flash ({})"
.format(node.path if node else "missing"))
out_comment(f"/chosen/zephyr,flash ({node.path if node else 'missing'})")
if not node:
# No flash node. Write dummy values.
@ -393,8 +390,8 @@ def write_flash_node(edt):
return
if len(node.regs) != 1:
err("expected zephyr,flash to have a single register, has {}"
.format(len(node.regs)))
err("expected zephyr,flash to have a single register, has "
f"{len(node.regs)}")
if node.on_bus == "spi" and len(node.bus_node.regs) == 2:
reg = node.bus_node.regs[1] # QSPI flash
@ -417,8 +414,8 @@ def write_code_partition(edt):
node = edt.chosen_node("zephyr,code-partition")
out_comment("/chosen/zephyr,code-partition ({})"
.format(node.path if node else "missing"))
out_comment("/chosen/zephyr,code-partition "
f"({node.path if node else 'missing'})")
if not node:
# No code partition. Write dummy values.
@ -427,7 +424,7 @@ def write_code_partition(edt):
return
if not node.regs:
err("missing 'regs' property on {!r}".format(node))
err(f"missing 'regs' property on {node!r}")
out("CODE_PARTITION_OFFSET", node.regs[0].addr)
out("CODE_PARTITION_SIZE", node.regs[0].size)
@ -437,36 +434,35 @@ def write_flash_partition(partition_node, index):
out_comment("Flash partition at " + partition_node.path)
if partition_node.label is None:
err("missing 'label' property on {!r}".format(partition_node))
err(f"missing 'label' property on {partition_node!r}")
# Generate label-based identifiers
write_flash_partition_prefix(
"FLASH_AREA_" + str2ident(partition_node.label), partition_node, index)
# Generate index-based identifiers
write_flash_partition_prefix(
"FLASH_AREA_{}".format(index), partition_node, index)
write_flash_partition_prefix(f"FLASH_AREA_{index}", partition_node, index)
def write_flash_partition_prefix(prefix, partition_node, index):
# write_flash_partition() helper. Generates identifiers starting with
# 'prefix'.
out("{}_ID".format(prefix), index)
out(f"{prefix}_ID", index)
out("{}_READ_ONLY".format(prefix), 1 if partition_node.read_only else 0)
out(f"{prefix}_READ_ONLY", 1 if partition_node.read_only else 0)
for i, reg in enumerate(partition_node.regs):
# Also add aliases that point to the first sector (TODO: get rid of the
# aliases?)
out("{}_OFFSET_{}".format(prefix, i), reg.addr,
aliases=["{}_OFFSET".format(prefix)] if i == 0 else [])
out("{}_SIZE_{}".format(prefix, i), reg.size,
aliases=["{}_SIZE".format(prefix)] if i == 0 else [])
out(f"{prefix}_OFFSET_{i}", reg.addr,
aliases=[f"{prefix}_OFFSET"] if i == 0 else [])
out(f"{prefix}_SIZE_{i}", reg.size,
aliases=[f"{prefix}_SIZE"] if i == 0 else [])
controller = partition_node.flash_controller
if controller.label is not None:
out_s("{}_DEV".format(prefix), controller.label)
out_s(f"{prefix}_DEV", controller.label)
def write_irqs(node):
@ -477,24 +473,23 @@ def write_irqs(node):
if not irq.name:
return None
alias = "IRQ_{}".format(str2ident(irq.name))
alias = f"IRQ_{str2ident(irq.name)}"
if cell_name != "irq":
alias += "_" + str2ident(cell_name)
alias += f"_{str2ident(cell_name)}"
return alias
def map_arm_gic_irq_type(irq, irq_num):
# Maps ARM GIC IRQ (type)+(index) combo to linear IRQ number
if "type" not in irq.data:
err("Expected binding for {!r} to have 'type' in interrupt-cells"
.format(irq.controller))
err(f"Expected binding for {irq.controller!r} to have 'type' in "
"interrupt-cells")
irq_type = irq.data["type"]
if irq_type == 0: # GIC_SPI
return irq_num + 32
if irq_type == 1: # GIC_PPI
return irq_num + 16
err("Invalid interrupt type specified for {!r}"
.format(irq))
err(f"Invalid interrupt type specified for {irq!r}")
def encode_zephyr_multi_level_irq(irq, irq_num):
# See doc/reference/kernel/other/interrupts.rst for details
@ -505,21 +500,21 @@ def write_irqs(node):
while irq_ctrl.interrupts:
irq_num = (irq_num + 1) << 8
if "irq" not in irq_ctrl.interrupts[0].data:
err("Expected binding for {!r} to have 'irq' in interrupt-cells"
.format(irq_ctrl))
err(f"Expected binding for {irq_ctrl!r} to have 'irq' in "
"interrupt-cells")
irq_num |= irq_ctrl.interrupts[0].data["irq"]
irq_ctrl = irq_ctrl.interrupts[0].controller
return irq_num
for irq_i, irq in enumerate(node.interrupts):
for cell_name, cell_value in irq.data.items():
ident = "IRQ_{}".format(irq_i)
ident = f"IRQ_{irq_i}"
if cell_name == "irq":
if "arm,gic" in irq.controller.compats:
cell_value = map_arm_gic_irq_type(irq, cell_value)
cell_value = encode_zephyr_multi_level_irq(irq, cell_value)
else:
ident += "_" + str2ident(cell_name)
ident += f"_{str2ident(cell_name)}"
out_node(node, ident, cell_value,
name_alias=irq_name_alias(irq, cell_name))
@ -586,37 +581,37 @@ def write_phandle_val_list_entry(node, entry, i, ident):
if entry.controller.label is not None:
ctrl_ident = ident + "_CONTROLLER" # e.g. PWMS_CONTROLLER
if entry.name:
name_alias = str2ident(entry.name) + "_" + ctrl_ident
name_alias = f"{str2ident(entry.name)}_{ctrl_ident}"
else:
name_alias = None
# Ugly backwards compatibility hack. Only add the index if there's
# more than one entry.
if i is not None:
ctrl_ident += "_{}".format(i)
ctrl_ident += f"_{i}"
initializer_vals.append(quote_str(entry.controller.label))
out_node_s(node, ctrl_ident, entry.controller.label, name_alias)
for cell, val in entry.data.items():
cell_ident = ident + "_" + str2ident(cell) # e.g. PWMS_CHANNEL
cell_ident = f"{ident}_{str2ident(cell)}" # e.g. PWMS_CHANNEL
if entry.name:
# From e.g. 'pwm-names = ...'
name_alias = str2ident(entry.name) + "_" + cell_ident
name_alias = f"{str2ident(entry.name)}_{cell_ident}"
else:
name_alias = None
# Backwards compatibility (see above)
if i is not None:
cell_ident += "_{}".format(i)
cell_ident += f"_{i}"
out_node(node, cell_ident, val, name_alias)
initializer_vals += entry.data.values()
initializer_ident = ident
if entry.name:
name_alias = initializer_ident + "_" + str2ident(entry.name)
name_alias = f"{initializer_ident}_{str2ident(entry.name)}"
else:
name_alias = None
if i is not None:
initializer_ident += "_{}".format(i)
initializer_ident += f"_{i}"
return out_node_init(node, initializer_ident, initializer_vals, name_alias)
@ -644,15 +639,15 @@ def write_clocks(node):
else:
clk_name_alias = None
out_node(node, "CLOCK_{}_{}".format(str2ident(name), clock_i), val,
out_node(node, f"CLOCK_{str2ident(name)}_{clock_i}", val,
name_alias=clk_name_alias)
if "fixed-clock" not in controller.compats:
continue
if "clock-frequency" not in controller.props:
err("{!r} is a 'fixed-clock' but lacks a 'clock-frequency' "
"property".format(controller))
err(f"{controller!r} is a 'fixed-clock' but lacks a "
"'clock-frequency' property")
out_node(node, "CLOCKS_CLOCK_FREQUENCY",
controller.props["clock-frequency"].val)
@ -692,12 +687,12 @@ def out_node(node, ident, val, name_alias=None):
node_prefix = node_ident(node)
aliases = [alias + "_" + ident for alias in node_aliases(node)]
aliases = [f"{alias}_{ident}" for alias in node_aliases(node)]
if name_alias is not None:
aliases.append(node_prefix + "_" + name_alias)
aliases += [alias + "_" + name_alias for alias in node_aliases(node)]
aliases.append(f"{node_prefix}_{name_alias}")
aliases += [f"{alias}_{name_alias}" for alias in node_aliases(node)]
return out(node_prefix + "_" + ident, val, aliases)
return out(f"{node_prefix}_{ident}", val, aliases)
def out_node_s(node, ident, s, name_alias=None):
@ -737,8 +732,8 @@ def out(ident, val, aliases=()):
#
# Returns the generated macro name for 'ident'.
print("#define DT_{:40} {}".format(ident, val), file=header_file)
primary_ident = "DT_{}".format(ident)
print(f"#define DT_{ident:40} {val}", file=header_file)
primary_ident = f"DT_{ident}"
# Exclude things that aren't single token values from .conf. At
# the moment the only such items are unquoted string
@ -746,16 +741,15 @@ def out(ident, val, aliases=()):
# brace.
output_to_conf = not (isinstance(val, str) and val.startswith("{"))
if output_to_conf:
print("{}={}".format(primary_ident, val), file=conf_file)
print(f"{primary_ident}={val}", file=conf_file)
for alias in aliases:
if alias != ident:
print("#define DT_{:40} DT_{}".format(alias, ident),
file=header_file)
print(f"#define DT_{alias:40} DT_{ident}", file=header_file)
if output_to_conf:
# For the configuration file, the value is just repeated for all
# the aliases
print("DT_{}={}".format(alias, val), file=conf_file)
print(f"DT_{alias}={val}", file=conf_file)
return primary_ident
@ -805,7 +799,7 @@ def quote_str(s):
# Puts quotes around 's' and escapes any double quotes and
# backslashes within it
return '"{}"'.format(escape(s))
return f'"{escape(s)}"'
def err(s):