block: don't put spaces around :
[ironout.git] / find.c
blob42ac64eef3d64de06aab9be42b78d7828b177452
1 #include <stdlib.h>
2 #include <string.h>
3 #include "find.h"
4 #include "utils.h"
7 struct finddata {
8 struct cfile *cfile;
9 struct block *block;
10 struct name *name;
11 struct hit *hit;
14 static int extern_node_matches(struct name *expected, struct node *node)
16 int flags = guess_name_flags(node);
17 if (!modifiers_match(expected, flags) || expected->flags & NAME_STATIC)
18 return 0;
19 return !(flags & (NAME_FIELD | NAME_PARAMDECL));
22 static int does_match(struct node *node, void *data)
24 struct finddata *finddata = data;
25 if ((node->type == AST_IDENTIFIER || node->type == AST_TYPENAME) &&
26 !strcmp(finddata->name->name, node->data)) {
27 struct block *block = block_find(finddata->block, node->start);
28 struct name *name = block_lookup(block, node);
29 if ((!name && extern_node_matches(finddata->name, node)) ||
30 name == finddata->name) {
31 struct hit *hit = xmalloc(sizeof(struct hit));
32 hit->start = node->start;
33 hit->end = node->end;
34 hit->cfile = finddata->cfile;
35 hit->next = finddata->hit;
36 finddata->hit = hit;
39 /* don't check nodes outside defining block */
40 return 1;
43 static struct hit *reverse(struct hit *o)
45 struct hit *newhead = NULL;
46 struct hit *cur = o;
47 while (cur) {
48 struct hit *next = cur->next;
49 cur->next = newhead;
50 newhead = cur;
51 cur = next;
53 return newhead;
56 struct hit *find_name(struct project *project, struct name *name)
58 if (name) {
59 struct finddata finddata;
60 int i;
61 finddata.hit = NULL;
62 finddata.name = name;
63 for (i = project->count - 1; i >= 0; --i) {
64 struct cfile *cur = project->files[i];
65 finddata.block = cur->block;
66 finddata.cfile = cur;
67 node_walk(cur->node, does_match, &finddata);
69 return reverse(finddata.hit);
71 return NULL;
74 void free_hits(struct hit *hit_list)
76 struct hit *cur = hit_list;
77 while (cur) {
78 struct hit *next = cur->next;
79 free(cur);
80 cur = next;