master xplshn/aruu / cmd / dev / ninqu / registry.c
  1#include "ninqu.h"
  2
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <string.h>
  6
  7struct Rule     *rules;
  8int              nrules, rulescap;
  9struct Group    *groups;
 10int              ngroups, groupscap;
 11struct Meta     *metas;
 12int              nmetas, metascap;
 13struct Template *templates;
 14int              ntemplates, templatescap;
 15struct Inst     *insts;
 16int              ninsts, instscap;
 17
 18struct Rule *
 19rule_find(const char *name)
 20{
 21  int i;
 22  for (i = 0; i < nrules; i++)
 23    if (strcmp(rules[i].name, name) == 0)
 24      return &rules[i];
 25  return NULL;
 26}
 27
 28/* match (out) against path, expanding $(...) as needed. used to
 29 * find a producer for a file that does not exist yet */
 30struct Rule *
 31rule_find_output(const char *path)
 32{
 33  int i;
 34  for (i = 0; i < nrules; i++) {
 35    if (!rules[i].out[0])
 36      continue;
 37    if (strchr(rules[i].out, '$')) {
 38      char *exp = kv_expand(rules[i].out);
 39      int   ok  = strcmp(exp, path) == 0;
 40      free(exp);
 41      if (ok)
 42        return &rules[i];
 43    } else if (strcmp(rules[i].out, path) == 0) {
 44      return &rules[i];
 45    }
 46  }
 47  return NULL;
 48}
 49
 50struct Rule *
 51rule_find_produces(const char *name)
 52{
 53  int i;
 54  for (i = 0; i < nrules; i++)
 55    if (rules[i].produces[0] && strcmp(rules[i].produces, name) == 0)
 56      return &rules[i];
 57  return NULL;
 58}
 59
 60struct Rule *
 61rule_new(const char *name)
 62{
 63  struct Rule *r;
 64  if (rule_find(name))
 65    eprintf("manifest: duplicate rule '%s'\n", name);
 66  if (group_find(name))
 67    eprintf("manifest: name '%s' already a group\n", name);
 68  GROW(rules, nrules, rulescap, 16);
 69  r = &rules[nrules++];
 70  memset(r, 0, sizeof *r);
 71  strlcpy(r->name, name, sizeof r->name);
 72  return r;
 73}
 74
 75struct Group *
 76group_find(const char *name)
 77{
 78  int i;
 79  for (i = 0; i < ngroups; i++)
 80    if (strcmp(groups[i].name, name) == 0)
 81      return &groups[i];
 82  return NULL;
 83}
 84
 85struct Group *
 86group_new(const char *name)
 87{
 88  struct Group *g;
 89  if (group_find(name))
 90    eprintf("manifest: duplicate group '%s'\n", name);
 91  if (rule_find(name))
 92    eprintf("manifest: name '%s' already a rule\n", name);
 93  GROW(groups, ngroups, groupscap, 16);
 94  g = &groups[ngroups++];
 95  memset(g, 0, sizeof *g);
 96  strlcpy(g->name, name, sizeof g->name);
 97  return g;
 98}
 99
100struct Meta *
101meta_find(const char *name)
102{
103  int i;
104  for (i = 0; i < nmetas; i++)
105    if (strcmp(metas[i].name, name) == 0)
106      return &metas[i];
107  return NULL;
108}
109
110struct Meta *
111meta_new(const char *name)
112{
113  struct Meta *m;
114  if (meta_find(name))
115    eprintf("manifest: duplicate meta '%s'\n", name);
116  if (rule_find(name))
117    eprintf("manifest: name '%s' already a rule\n", name);
118  if (group_find(name))
119    eprintf("manifest: name '%s' already a group\n", name);
120  GROW(metas, nmetas, metascap, 8);
121  m = &metas[nmetas++];
122  memset(m, 0, sizeof *m);
123  strlcpy(m->name, name, sizeof m->name);
124  return m;
125}
126
127struct Template *
128template_find(const char *name)
129{
130  int i;
131  for (i = 0; i < ntemplates; i++)
132    if (strcmp(templates[i].name, name) == 0)
133      return &templates[i];
134  return NULL;
135}
136
137struct Template *
138template_new(const char *name)
139{
140  struct Template *t;
141  if (template_find(name))
142    eprintf("manifest: duplicate template '%s'\n", name);
143  GROW(templates, ntemplates, templatescap, 8);
144  t = &templates[ntemplates++];
145  memset(t, 0, sizeof *t);
146  strlcpy(t->name, name, sizeof t->name);
147  return t;
148}
149
150int
151inst_new(int rule_idx)
152{
153  struct Inst *in;
154  struct Rule *r = &rules[rule_idx];
155
156  GROW(insts, ninsts, instscap, 32);
157  in = &insts[ninsts];
158  memset(in, 0, sizeof *in);
159  in->rule_idx = rule_idx;
160
161  if (r->n_inst >= r->cap_inst) {
162    r->cap_inst = r->cap_inst ? r->cap_inst * 2 : 4;
163    r->inst_idx = erealloc(r->inst_idx, (size_t)r->cap_inst * sizeof *r->inst_idx);
164  }
165  r->inst_idx[r->n_inst++] = ninsts;
166  return ninsts++;
167}