#! /usr/bin/env python3 import getopt import sys import os import fxconv help_string = """ usage: fxconv [-s] [files...] fxconv -b -o [parameters...] fxconv -i -o (--fx|--cg) [parameters...] fxconv -f -o [parameters...] fxconv converts data files such as images and fonts into gint formats optimized for fast execution, or into object files. Operating modes: -s, --script Expose the fxconv module and run this Python script -b, --binary Turn data into an object file, no conversion -i, --image Convert to gint's image format -f, --font Convert to gint's font format When using -s, additional arguments are stored in the [fxconv.args] variable of the module. This is intended to be a restricted list of file names specified by a Makefile, used to convert only a subset of the files in the script. The -b, -i and -f modes are shortcuts to convert single files without a script. They accept parameters with a "category.key:value" syntax, for example: fxconv -f myfont.png -o myfont.o charset:ascii grid.padding:1 height:7 When converting images, use --fx (black-and-white calculators) or --cg (16-bit color calculators) to specify the target machine. """.strip() # Simple error-warnings system def err(msg): print("\x1b[31;1merror:\x1b[0m", msg, file=sys.stderr) def warn(msg): print("warning:", msg, file=sys.stderr) def main(): # Default execution mode is to run a Python script for conversion modes = "script binary image font" mode = "s" output = None target = None # Parse command-line arguments if len(sys.argv) == 1: print(help_string, file=sys.stderr) sys.exit(1) try: opts, args = getopt.gnu_getopt(sys.argv[1:], "hsbifo:", ("help output= fx cg "+modes).split()) except getopt.GetoptError as error: err(error) sys.exit(1) for name, value in opts: # Print usage if name == "--help": err(help_string, file=sys.stderr) sys.exit(0) # TODO: fxconv: verbose mode elif name == "--verbose": pass elif name in [ "-o", "--output" ]: output = value elif name in [ "--fx", "--cg" ]: target = name[2:] # Other names are modes else: mode = name[1] if len(name)==2 else name[2] # Remaining arguments if args == []: err(f"execution mode -{mode} expects an input file") sys.exit(1) input = args.pop(0) # In --script mode, run the Python script with an augmented PYTHONPATH if mode == "s": if output is not None: warn("option --output is ignored in script mode") args = None if args == [] else args err("script mode not currently implemented (TODO) x_x") sys.exit(1) # In shortcut conversion modes, read parameters from the command-line else: def check(arg): if ':' not in arg: warn(f"argument {arg} is not a valid parameter (ignored)") return ':' in arg def insert(params, path, value): if len(path) == 1: params[path[0]] = value return if not path[0] in params: params[path[0]] = {} insert(params[path[0]], path[1:], value) args = [ arg.split(':', 1) for arg in args if check(arg) ] params = {} for (name, value) in args: insert(params, name.split("."), value) params["type"] = { "b": "binary", "i": "image", "f": "font" }[mode] try: fxconv.convert(input, params, output, target) except fxconv.FxconvError as e: err(e) sys.exit(1) if __name__ == "__main__": main()