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 Env {
212 struct Var *v;
213 size_t n;
214 size_t cap;
215};
216
217struct Target {
218 const char *name; /* interned */
219 char *owner;
220 struct StrList prereqs;
221 struct StrList impprereqs;
222 struct StrList order_only;
223 struct RecipeList recipes;
224 struct Env env;
225 int dcolon;
226 int defined;
227 int phony;
228};
229
230struct SubGraph;
231
232struct Graph {
233 struct Target *v;
234 size_t n;
235 struct SubGraph *subs;
236 size_t nsubs;
237};
238
239struct SubGraph {
240 char *cwd;
241 char *prefix;
242 char *makefile;
243 struct StrList parents;
244 struct StrList envassigns;
245 struct StrList assigns;
246 struct StrList flags;
247 struct StrList goals;
248 struct Graph graph;
249 enum ShinMode mode;
250};
251
252int preproc(const char *path, struct Pre *pre, enum ShinMode mode);
253void freepre(struct Pre *pre);
254int buildast(const char *path, const struct Pre *pre, struct Ast *ast, enum ShinMode mode);
255int eval(const char *path, const struct Ast *ast, const struct Ast *pre, int envoverride, enum ShinMode mode, struct RuleSet *out);
256int parse(const char *path, const char *src, struct Ast *ast, enum ShinMode mode);
257void freeast(struct Ast *ast);
258void freeruleset(struct RuleSet *ruleset);
259int buildgraph(const struct RuleSet *ruleset, const struct StrList *goals, struct Graph *graph, enum ShinMode mode);
260int expandgraph(struct Graph *graph, enum ShinMode mode);
261void freegraph(struct Graph *graph);
262int buildsubgraph(struct SubGraph *sg);
263void freesubgraph(struct SubGraph *sg);
264
265#endif