master xplshn/aruu / cmd / dev / ninqu / ninqu.h
  1#if !defined(_DEFAULT_SOURCE)
  2#define _DEFAULT_SOURCE
  3#endif
  4#if !defined(_POSIX_C_SOURCE)
  5#define _POSIX_C_SOURCE 200809L
  6#endif
  7
  8#include <sys/types.h>
  9
 10#include "arg.h"
 11#include "util.h"
 12
 13/* grow a struct-array when full, n/cap doubles each time */
 14#define GROW(arr, n, cap, init)                                                                    \
 15  do {                                                                                             \
 16    if ((n) >= (cap)) {                                                                            \
 17      (cap) = (cap) ? (cap) * 2 : (init);                                                          \
 18      (arr) = erealloc((arr), (size_t)(cap) * sizeof *(arr));                                      \
 19    }                                                                                              \
 20  } while (0)
 21
 22struct StrList {
 23  char **v;
 24  int    n;
 25  int    cap;
 26};
 27
 28void        sl_push(struct StrList *sl, const char *s);
 29int         sl_has(struct StrList *sl, const char *s);
 30void        sl_split(struct StrList *sl, const char *s);
 31char       *sl_join(struct StrList *sl);
 32char      **sl_argv(struct StrList *sl);
 33const char *base_of(const char *path);
 34void        child_execvp(char **av) __attribute__((noreturn));
 35
 36struct Kv {
 37  char *key;
 38  char *val;
 39};
 40
 41struct KvStore {
 42  struct Kv *v;
 43  int        n, cap;
 44};
 45
 46struct Map {
 47  char           name[128];
 48  struct KvStore entries;
 49};
 50
 51char       *kv_get(const char *key);
 52const char *kv_get_or(const char *key, const char *def);
 53void        kv_set(const char *key, const char *val);
 54void        kv_set_manifest(const char *key, const char *val);
 55void        kv_set_cli(const char *key, const char *val);
 56char       *kv_expand(const char *s);
 57char       *kv_get_raw(struct KvStore *s, const char *key);
 58void        kv_set_raw(struct KvStore *s, const char *key, const char *val);
 59struct Map *map_find(const char *name);
 60struct Map *map_new(const char *name);
 61
 62extern struct KvStore  kv;
 63extern struct KvStore *local_overlay;
 64extern struct StrList  kv_locked;
 65extern struct Map     *maps;
 66extern int             nmaps, mapscap;
 67
 68enum SKind { S_ATOM, S_LIST };
 69
 70struct SNode {
 71  enum SKind     kind;
 72  char          *atom;
 73  struct SNode **kids;
 74  int            nkids;
 75  int            line;
 76};
 77
 78struct SLex {
 79  const char *src;
 80  size_t      pos;
 81  int         line;
 82};
 83
 84struct SNode *snode_atom(const char *s, int line);
 85struct SNode *snode_list(int line);
 86void          snode_push(struct SNode *list, struct SNode *kid);
 87void          snode_free(struct SNode *n);
 88struct SNode *snode_clone(struct SNode *n);
 89struct SNode *snode_parse(struct SLex *lx);
 90int           s_is_list(struct SNode *n);
 91const char   *s_head(struct SNode *n);
 92char         *subst_tmpl(const char *s, struct StrList *params, char **vals);
 93void          snode_subst(struct SNode *n, struct StrList *params, char **vals);
 94void          lex_swallow_dollar(struct SLex *lx, char *buf, size_t *blen, size_t bsz);
 95void          lex_string(struct SLex *lx, char *buf, size_t bsz);
 96const char   *find_dollar_close(const char *inner);
 97
 98/* gate: (not X) | (and X...) | (or X...) | bare var */
 99enum GKind { G_TRUE, G_VAR, G_NOT, G_AND, G_OR };
100
101struct Gate {
102  enum GKind    kind;
103  char         *var;
104  struct Gate **kids;
105  int           nkids;
106};
107
108struct Gate *gate_new(enum GKind kind);
109void         gate_free(struct Gate *g);
110struct Gate *gate_parse(struct SNode *expr);
111int          gate_has_dyn(struct Gate *g);
112int          gate_eval(struct Gate *g);
113struct Gate *gate_materialize(struct Gate *g);
114
115struct Cmd {
116  struct StrList   argv;
117  int              is_pipe;
118  struct StrList **stages;
119  int              nstages;
120};
121
122struct Rule {
123  char           name[128];
124  struct StrList globs;
125  struct StrList skip;
126  char           require_marker[1024];
127  char           require_file[1024];
128  struct StrList in;
129  struct StrList extra_deps;
130  char           out[1024];
131  struct Cmd     cmd;
132  struct Gate   *gate;
133  char           workdir[1024];
134  int            phony;
135  int            redirect;
136  char           produces[128];
137  char           description[256];
138  char           group_name[128];
139  char           member_of[128];
140  char           member_alias[128];
141  struct StrList features;
142
143  int *inst_idx;
144  int  n_inst, cap_inst;
145  int  expanded;
146};
147
148struct Group {
149  char           name[128];
150  struct StrList refs;
151};
152
153struct Meta {
154  char           name[128];
155  struct StrList keys;
156  struct StrList vals;
157};
158
159struct Template {
160  char           name[128];
161  struct StrList params;
162  struct SNode  *body;
163};
164
165struct Rule     *rule_find(const char *name);
166struct Rule     *rule_find_output(const char *path);
167struct Rule     *rule_find_produces(const char *name);
168struct Rule     *rule_new(const char *name);
169struct Group    *group_find(const char *name);
170struct Group    *group_new(const char *name);
171struct Meta     *meta_find(const char *name);
172struct Meta     *meta_new(const char *name);
173struct Template *template_find(const char *name);
174struct Template *template_new(const char *name);
175
176extern struct Rule     *rules;
177extern int              nrules, rulescap;
178extern struct Group    *groups;
179extern int              ngroups, groupscap;
180extern struct Meta     *metas;
181extern int              nmetas, metascap;
182extern struct Template *templates;
183extern int              ntemplates, templatescap;
184
185struct Inst {
186  int            rule_idx;
187  struct StrList in;
188  struct StrList stale_extra;
189  char           out[1024];
190  struct Cmd     cmd;
191  char           workdir[1024];
192  int            phony;
193  int            redirect;
194
195  struct StrList dep_rule_names;
196  int           *dep_inst;
197  int            n_dep, cap_dep;
198  int            will_build;
199};
200
201int  inst_new(int rule_idx);
202int  inst_stale(struct Inst *inst);
203void dep_push(struct Inst *inst, int idx);
204void resolve_deps(void);
205
206extern struct Inst *insts;
207extern int          ninsts, instscap;
208
209long mtime_of(const char *path);
210int  file_exists(const char *path);
211int  file_contains(const char *path, const char *needle);
212void glob_expand(const char *pattern, struct StrList *out);
213void glob_all(struct Rule *r, struct StrList *out);
214int  is_wildcard_pattern(const char *pattern);
215int  rule_is_literal(struct Rule *r);
216int  path_claimed_elsewhere(const char *path, struct Rule *self);
217void splitext(const char *base, char *stem, size_t stemsz, char *ext, size_t extsz);
218void to_ident(const char *s, char *out, size_t outsz);
219
220pid_t spawn_inst(struct Inst *inst, struct StrList *argv);
221pid_t spawn_pipe(struct Inst *inst);
222void  mk_out_dir(const char *out);
223void  announce_inst(struct Inst *inst);
224void  run_inst_sync(int idx);
225void  run_batch(int *idxs, int n);
226void  run_inst_with_deps(int idx);
227void  materialize_if_missing(const char *path);
228char *capture_argv(struct StrList *argv);
229
230extern int jobs_n;
231extern int summary_mode;
232extern int failed_any;
233
234void        load_file(const char *path);
235void        load_manifest(struct SNode *root);
236void        dispatch_top_form(struct SNode *form);
237void        parse_exec_clause(struct SNode *clause, struct Cmd *cmd);
238void        parse_shell_clause(struct SNode *clause, struct Cmd *cmd);
239void        parse_pipe_clause(struct SNode *clause, struct Cmd *cmd);
240void        meta_apply(struct Meta *m);
241const char *first_atom(struct SNode *node, const char *msg);
242const char *sole_atom(struct SNode *node, const char *msg);
243
244extern struct StrList files_read;
245
246void expand_rule(const char *name);
247
248void schedule_and_run(void);
249void emit_ninja(const char *path, struct StrList *wanted);
250
251struct Backend {
252  const char *name;
253  const char *try_key;
254  const char *file;
255  void (*emit)(const char *path, struct StrList *wanted);
256};
257
258const struct Backend *backend_by_name(const char *name);
259const struct Backend *backend_resolve(char **bin);
260void backend_exec(const struct Backend *be, const char *bin, struct StrList *wanted)
261    __attribute__((noreturn));
262
263void do_features(void);
264void do_query(const char *sub, const char *arg);
265
266void include_ref(const char *name);
267void build_default_group(void);
268void resolve_wanted(const char *w);
269void resolve_all_bareword_deps(void);