XFTGenerator/XFTGenerator.py

212 lines
5.6 KiB
Python
Raw Normal View History

2023-07-11 13:10:15 +00:00
# XF Template Generator
__author__ = "Louis Heredero"
__copyright__ = "Copyright 2023, Louis Heredero"
__license__ = "GPL3.0"
__version__ = "1.0.0"
import json
import locale
import os
import re
import time
2023-07-11 13:46:42 +00:00
def ucfirst(s):
return s[0].upper() + s[1:]
2023-07-11 13:10:15 +00:00
def get_input(title, default=None, non_null=False):
"""Prompts user for an input
Args:
title (str): Name of value
default (Any, optional): Default value. Defaults to None.
non_null (bool, optional): Whether the can be null. Defaults to False.
Returns:
str|None: The value
"""
while True:
txt = title
if default is not None:
txt += f" [{default}]"
txt += ": "
value = input(txt).strip()
if value:
return value
elif default:
return default
elif not non_null:
return ""
def fill_template(dir_, variables, filename):
"""Replaces values in a template file
Args:
dir_ (str): Path of src directory
variables (dict): Dictionary of values to replace
filename (str): Template file name
Returns:
str: Template content with replaced values
"""
with open(os.path.join(dir_, "templates", filename), "r") as f:
content = f.read()
def replace(m):
indent = m.group(1)
key = m.group(2)
txt = variables[key]
if indent:
lines = txt.split("\n")
lines = [indent+line for line in lines]
txt = "\n".join(lines)
return txt
return re.sub("([ \t]*)\$\{(.+?)\}", replace, content)
def output_file(dir_, filename, content):
"""Writes content to a given file. Checks before overwriting
Args:
dir_ (str): Path of src directory
filename (str): Output file name
content (str): Content to write
"""
outdir = os.path.join(dir_, "out")
if not os.path.isdir(outdir):
os.mkdir(outdir)
outpath = os.path.join(outdir, filename)
if os.path.exists(outpath):
replace = input(f"The file {filename} already exists. Overwrite it ? y/N: ")
if replace.lower() != "y":
return
with open(outpath, "w") as f:
f.write(content)
def main():
locale.setlocale(locale.LC_TIME, "en_GB.utf8")
dir_ = os.path.dirname(__file__)
2023-07-11 13:46:42 +00:00
# Load config if it exists
2023-07-11 13:10:15 +00:00
conf_path = os.path.join(dir_, "config.json")
if os.path.exists(conf_path):
with open(conf_path, "r") as f:
variables = json.load(f)
else:
variables = {}
variables["date"] = time.strftime("%B %Y")
variables["author"] = get_input("Author", variables.get("author", ""), True)
variables["filename"] = get_input("Filename", None, True).upper()
variables["filename_lc"] = variables["filename"].lower()
variables["fn"] = get_input("Filename (short)", None, True).upper()
##########
# States #
##########
states = []
print("States (leave empty to end):")
print("> INIT")
while True:
state = input("> ").upper()
if state:
states.append(state)
else:
break
states = ["ST"+variables["fn"]+"_"+s for s in states]
variables["STATES_ENUM"] = ",\n".join(states)
states_cases = []
2023-07-11 13:46:42 +00:00
for state in states:
2023-07-11 13:10:15 +00:00
case_ = f"case {state}:\n"
case_ += " break;"
states_cases.append(case_)
variables["STATES_CASES"] = "\n\n".join(states_cases)
##########
# Events #
##########
events = ["init = 100"]
print("Events (leave empty to end):")
print("> init")
while True:
event = input("> ").lower()
if event:
events.append(event)
else:
break
events_enum = ["ev"+variables["fn"]+e for e in events]
events_enum = ",\n".join(events_enum).split("\n")
events_enum[0] += " // TODO change this number (< 256)"
variables["EVENTS_ENUM"] = "\n".join(events_enum)
2023-07-11 13:46:42 +00:00
events_emits_def = []
2023-07-11 13:10:15 +00:00
emit_def = ""
emit_def += "void {filename}_emit{Event}({filename}* me, uint16_t t) {\n"
emit_def += " POST(me, &{filename}_processEvent, ev{fn}{event}, t, 0);\n"
emit_def += "}"
emit_def = emit_def.replace("{filename}", variables["filename"]).replace("{fn}", variables["fn"])
for event in events[1:]:
2023-07-11 13:46:42 +00:00
events_emits_def.append(
2023-07-11 13:10:15 +00:00
emit_def.replace("{event}", event).replace("{Event}", event.capitalize())
)
2023-07-11 13:46:42 +00:00
variables["EVENTS_EMITS_DEF"] = "\n\n".join(events_emits_def)
2023-07-11 13:10:15 +00:00
2023-07-11 13:46:42 +00:00
events_emits_dec = []
2023-07-11 13:10:15 +00:00
emit_dec = ""
emit_dec += "/**\n"
emit_dec += " * Emit the {event} event\n"
emit_dec += " * @param me the {filename} itself\n"
emit_dec += " * @param t time to wait in ms before triggering event\n"
emit_dec += " */"
emit_dec += "void {filename}_emit{Event}({filename}* me, uint16_t t);"
emit_dec = emit_dec.replace("{filename}", variables["filename"])
for event in events[1:]:
2023-07-11 13:46:42 +00:00
events_emits_dec.append(
2023-07-11 13:10:15 +00:00
emit_dec.replace("{event}", event).replace("{Event}", event.capitalize())
)
2023-07-11 13:46:42 +00:00
variables["EVENTS_EMITS_DEC"] = "\n\n".join(events_emits_dec)
##################
# Fill templates #
##################
2023-07-11 13:10:15 +00:00
file_c = fill_template(dir_, variables, "file.c")
file_h = fill_template(dir_, variables, "file.h")
output_file(dir_, variables["filename_lc"]+".c", file_c)
output_file(dir_, variables["filename_lc"]+".h", file_h)
2023-07-11 13:46:42 +00:00
# Save config
2023-07-11 13:10:15 +00:00
with open(conf_path, "w") as f:
conf = {
"author": variables["author"]
}
json.dump(conf, f)
if __name__ == "__main__":
main()