1-- 2-- SPDX-License-Identifier: BSD-2-Clause 3-- 4-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org> 5-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 6-- 7 8local util = require("tools.util") 9 10local generator = {} 11 12generator.__index = generator 13 14-- Wrapper for Lua write() best practice, for a simpler write call. 15function generator:write(line) 16 assert(self.gen:write(line)) 17end 18 19-- 20-- A write macro for the PAD64 preprocessor directive. 21-- Used for 32-bit configurations by passing config.abiChanges("pair_64bit") and 22-- padding will be done if necessary. 23-- 24-- PARAM: bool, TRUE to pad. 25-- 26function generator:pad64(bool) 27 if bool then 28 self:write([[ 29#if !defined(PAD64_REQUIRED) && !defined(__amd64__) 30#define PAD64_REQUIRED 31#endif 32]]) 33 end 34end 35 36-- Returns the generated tag. 37function generator:tag() 38 return self.tag 39end 40 41generator.storage_levels = {} 42 43-- Optional level to specify which order to store in, which defaults to one if 44-- not provided. 45function generator:store(str, level) 46 level = level or 1 47 self.storage_levels[level] = self.storage_levels[level] or {} 48 table.insert(self.storage_levels[level], str) 49end 50 51-- Write all storage in the order it was stored. 52function generator:writeStorage() 53 if self.storage_levels ~= nil then 54 for _, v in util.ipairsSparse(self.storage_levels) do 55 for _, line in ipairs(v) do 56 generator:write(line) 57 end 58 end 59 end 60end 61 62-- 63-- Writes the generated preamble. Default comment is C comments. 64-- 65-- PARAM: String str, the title for the file. 66-- 67-- PARAM: String comment, nil or optional to change comment (e.g., "#" for sh 68-- comments). 69-- 70-- SEE: style(9) 71-- 72function generator:preamble(str, comment) 73 if str ~= nil then 74 local comment_start = comment or "/*" 75 local comment_middle = comment or " *" 76 local comment_end = comment or " */" 77 self:write(string.format("%s\n", comment_start)) 78 -- Splits our string into lines split by newline, or is just the 79 -- original string if there's no newlines. 80 for line in str:gmatch("[^\n]*") do 81 -- Only add a space after the comment if there's 82 -- text on this line. 83 local space 84 if line ~= "" then 85 space = " " 86 else 87 space = "" 88 end 89 -- Make sure to append the newline back. 90 self:write(string.format("%s%s%s\n", comment_middle, 91 space, line)) 92 end 93 self:write(string.format([[%s 94%s DO NOT EDIT-- this file is automatically %s. 95%s 96 97]], comment_middle, comment_middle, self.tag, comment_end)) 98 end 99end 100 101-- generator binds to the parameter file. 102function generator:new(obj, fh) 103 obj = obj or { } 104 setmetatable(obj, self) 105 self.__index = self 106 107 self.gen = assert(io.open(fh, "w+")) 108 self.tag = "@" .. "generated" 109 110 return obj 111end 112 113return generator 114