1#!/usr/bin/env python 2# 3# Copyright (C) 2020-2021 by 4# David Turner, Robert Wilhelm, and Werner Lemberg. 5# 6# This file is part of the FreeType project, and may only be used, modified, 7# and distributed under the terms of the FreeType project license, 8# LICENSE.TXT. By continuing to use, modify, or distribute this file you 9# indicate that you have read the license and understand and accept it 10# fully. 11 12"""Parse modules.cfg and dump its output either as ftmodule.h or a list of 13base extensions. 14""" 15 16from __future__ import print_function 17 18import argparse 19import os 20import re 21import sys 22 23# Expected input: 24# 25# ... 26# FONT_MODULES += <name> 27# HINTING_MODULES += <name> 28# RASTER_MODULES += <name> 29# AUX_MODULES += <name> 30# BASE_EXTENSIONS += <name> 31# ... 32 33 34def parse_modules_cfg(input_file): 35 36 lists = { 37 "FONT_MODULES": [], 38 "HINTING_MODULES": [], 39 "RASTER_MODULES": [], 40 "AUX_MODULES": [], 41 "BASE_EXTENSIONS": [], 42 } 43 44 for line in input_file.splitlines(): 45 line = line.rstrip() 46 # Ignore empty lines and those that start with a comment. 47 if not line or line[0] == "#": 48 continue 49 50 items = line.split() 51 assert len(items) == 3 and items[1] == "+=", ( 52 "Unexpected input line [%s]" % line 53 ) 54 assert items[0] in lists, ( 55 "Unexpected configuration variable name " + items[0] 56 ) 57 58 lists[items[0]].append(items[2]) 59 60 return lists 61 62 63def generate_ftmodule(lists): 64 result = "/* This is a generated file. */\n" 65 for driver in lists["FONT_MODULES"]: 66 if driver == "sfnt": # Special case for the sfnt 'driver'. 67 result += "FT_USE_MODULE( FT_Module_Class, sfnt_module_class )\n" 68 continue 69 70 name = { 71 "truetype": "tt", 72 "type1": "t1", 73 "cid": "t1cid", 74 "type42": "t42", 75 "winfonts": "winfnt", 76 }.get(driver, driver) 77 result += ( 78 "FT_USE_MODULE( FT_Driver_ClassRec, %s_driver_class )\n" % name 79 ) 80 81 for module in lists["HINTING_MODULES"]: 82 result += ( 83 "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module 84 ) 85 86 for module in lists["RASTER_MODULES"]: 87 name = { 88 "raster": "ft_raster1", 89 "smooth": "ft_smooth", 90 }.get(module) 91 result += ( 92 "FT_USE_MODULE( FT_Renderer_Class, %s_renderer_class )\n" % name 93 ) 94 95 for module in lists["AUX_MODULES"]: 96 if module in ("psaux", "psnames", "otvalid", "gxvalid"): 97 result += ( 98 "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module 99 ) 100 101 result += "/* EOF */\n" 102 return result 103 104 105def generate_main_modules(lists): 106 return "\n".join( 107 lists["FONT_MODULES"] 108 + lists["HINTING_MODULES"] 109 + lists["RASTER_MODULES"] 110 ) 111 112 113def generate_aux_modules(lists): 114 return "\n".join(lists["AUX_MODULES"]) 115 116 117def generate_base_extensions(lists): 118 return "\n".join(lists["BASE_EXTENSIONS"]) 119 120 121def main(): 122 parser = argparse.ArgumentParser(description=__doc__) 123 124 parser.add_argument( 125 "--format", 126 required=True, 127 choices=( 128 "ftmodule.h", 129 "main-modules", 130 "aux-modules", 131 "base-extensions-list", 132 ), 133 help="Select output format.", 134 ) 135 136 parser.add_argument( 137 "input", 138 metavar="CONFIGURE_RAW", 139 help="The input configure.raw file to parse.", 140 ) 141 142 parser.add_argument("--output", help="Output file (default is stdout).") 143 144 args = parser.parse_args() 145 with open(args.input) as f: 146 input_data = f.read() 147 148 lists = parse_modules_cfg(input_data) 149 150 if args.format == "ftmodule.h": 151 result = generate_ftmodule(lists) 152 elif args.format == "main-modules": 153 result = generate_main_modules(lists) 154 elif args.format == "aux-modules": 155 result = generate_aux_modules(lists) 156 elif args.format == "base-extensions-list": 157 result = generate_base_extensions(lists) 158 else: 159 assert False, "Invalid output format!" 160 161 if args.output: 162 with open(args.output, "w") as f: 163 f.write(result) 164 else: 165 print(result) 166 return 0 167 168 169if __name__ == "__main__": 170 sys.exit(main()) 171