main shrub/shinobi / src / shinobi.h
  1#ifndef SHINOBI_H
  2#define SHINOBI_H
  3
  4#include <stddef.h>
  5
  6/* -M flag: controls the makefile dialect accepted at eval time */
  7enum ShinMode {
  8	MODE_GNU = 0,
  9	MODE_POSIX_2024,
 10	MODE_POSIX_2008,
 11};
 12
 13/*
 14 * types
 15 * PreLine: one preprocessed line with source location
 16 * Pre: flattened preprocessed makefile input
 17 * Node: one parsed syntax node
 18 * Ast: parsed nodes in source order with nested cond blocks
 19 */
 20
 21struct ArenaBlock;
 22
 23struct Arena {
 24	struct ArenaBlock *head;
 25	size_t block_size;
 26};
 27
 28enum NodeKind {
 29	NODE_BLANK,
 30	NODE_COMMENT,
 31	NODE_ASSIGN,
 32	NODE_RULE,
 33	NODE_INCLUDE,
 34	NODE_COND,
 35	NODE_EXPORT,
 36	NODE_RAW,
 37};
 38
 39enum AssignOp {
 40	ASSIGN_EQ,
 41	ASSIGN_PLUS_EQ,
 42	ASSIGN_DCOLON_EQ,
 43	ASSIGN_COLON_EQ,
 44	ASSIGN_COLON3_EQ,
 45	ASSIGN_QMARK_EQ,
 46	ASSIGN_BANG_EQ,
 47};
 48
 49enum Origin {
 50	ORIGIN_DEFAULT,
 51	ORIGIN_ENV,
 52	ORIGIN_FILE,
 53	ORIGIN_ENV_OVERRIDE,
 54	ORIGIN_COMMAND,
 55	ORIGIN_OVERRIDE,
 56};
 57
 58enum CondKind {
 59	COND_IFEQ,
 60	COND_IFNEQ,
 61	COND_IFDEF,
 62	COND_IFNDEF,
 63	COND_ELSE,
 64	COND_ENDIF,
 65};
 66
 67struct SrcLoc {
 68	int line0;
 69	int line1;
 70};
 71
 72struct PreLine {
 73	char *path;
 74	char *text;
 75	int line0;
 76	int line1;
 77	int isrecipe;
 78	char recipeprefix;
 79};
 80
 81struct StrList {
 82	char **v;
 83	size_t n;
 84	size_t cap;
 85};
 86
 87struct Pre {
 88	struct PreLine *v;
 89	size_t n;
 90};
 91
 92struct SubMake {
 93	char *makeprog;
 94	char *dir;
 95	char *makefile;
 96	struct StrList assigns;
 97	struct StrList flags;
 98	struct StrList goals;
 99};
100
101struct Recipe {
102	char *body;
103	int silent;
104	int ignore;
105	int recursive;
106	int submake;
107	struct SubMake sm;
108};
109
110struct RecipeList {
111	struct Recipe *v;
112	size_t n;
113	size_t cap;
114};
115
116struct AssignNode {
117	char *lhs;
118	char *rhs;
119	enum AssignOp op;
120	enum Origin origin;
121	int exported;
122	int define_block;
123	int tspec;
124	struct StrList targets;
125};
126
127struct RuleNode {
128	struct StrList targets;
129	char *target_pattern;
130	struct StrList prereqs;
131	struct StrList order_only;
132	struct RecipeList recipes;
133	int dcolon;
134};
135
136struct IncludeNode {
137	int optional;
138	int sinclude;
139	char *path;
140};
141
142struct RawNode {
143	char *text;
144};
145
146struct ExportNode {
147	int all;
148	int exported;
149	struct StrList names;
150};
151
152struct Node;
153
154struct NodeList {
155	struct Node *v;
156	size_t n;
157	size_t cap;
158};
159
160struct CondNode {
161	enum CondKind kind;
162	char *arg1;
163	char *arg2;
164	char *raw;
165	struct NodeList thenpart;
166	struct NodeList elsepart;
167};
168
169struct Node {
170	enum NodeKind kind;
171	struct SrcLoc loc;
172	union StmtData {
173		struct AssignNode assign;
174		struct RuleNode rule;
175		struct IncludeNode include;
176		struct CondNode cond;
177		struct ExportNode export;
178		struct RawNode raw;
179	} data;
180};
181
182struct Ast {
183	struct Node *v;
184	size_t n;
185	size_t cap;
186	struct Arena arena;
187};
188
189struct RuleSet {
190	struct AssignNode *vars;
191	size_t nvars;
192	struct AssignNode *tvars;
193	size_t ntvars;
194	struct RuleNode *rules;
195	size_t nrules;
196	struct RecipeList defaultrule;
197	struct StrList phony;
198	int export_all;
199	int posix;
200	int envoverride;
201};
202
203struct Var {
204	const char *name; /* interned */
205	char *val;
206	int simple;
207	enum Origin origin;
208	int exported;
209};
210
211struct EnvIndexEnt;
212
213struct Env {
214	struct Var *v;
215	size_t n;
216	size_t cap;
217	struct EnvIndexEnt *varindex;
218	size_t nvarindex;
219	size_t cap_varindex;
220};
221
222struct Target {
223	const char *name; /* interned */
224	char *owner;
225	struct StrList prereqs;
226	struct StrList impprereqs;
227	struct StrList order_only;
228	struct RecipeList recipes;
229	struct Env env;
230	int dcolon;
231	int defined;
232	int phony;
233	int wanted;
234};
235
236struct SubGraph;
237struct GraphIndexEnt;
238
239struct Graph {
240	struct Target *v;
241	size_t n;
242	struct GraphIndexEnt *targetindex;
243	size_t ntargetindex;
244	size_t cap_targetindex;
245	struct SubGraph *subs;
246	size_t nsubs;
247};
248
249struct SubGraph {
250	char *cwd;
251	char *prefix;
252	char *makefile;
253	struct StrList parents;
254	struct StrList envassigns;
255	struct StrList assigns;
256	struct StrList flags;
257	struct StrList goals;
258	struct Graph graph;
259	enum ShinMode mode;
260	int wanted;
261};
262
263int preproc(const char *path, struct Pre *pre, enum ShinMode mode);
264void freepre(struct Pre *pre);
265int buildast(const char *path, const struct Pre *pre, struct Ast *ast, enum ShinMode mode);
266int eval(const char *path, const struct Ast *ast, const struct Ast *pre, int envoverride, enum ShinMode mode, struct RuleSet *out);
267int parse(const char *path, const char *src, struct Ast *ast, enum ShinMode mode);
268void freeast(struct Ast *ast);
269void freeruleset(struct RuleSet *ruleset);
270int buildgraph(const struct RuleSet *ruleset, const struct StrList *goals, struct Graph *graph, enum ShinMode mode);
271int expandgraph(struct Graph *graph, enum ShinMode mode);
272void freegraph(struct Graph *graph);
273int buildsubgraph(struct SubGraph *sg);
274void freesubgraph(struct SubGraph *sg);
275
276#endif