1 /*#include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>*/
4
5 #define LUA_CORE /* make sure that we don't try to import these functions */
6 #include <lua.h>
7 #include <lauxlib.h>
8
9 #include "path.h"
10 #include "context.h"
11 #include "mem.h"
12 #include "node.h"
13 #include "support.h"
14 #include "luafuncs.h"
15
16 struct DEPPLAIN
17 {
18 struct STRINGLIST *firstpath;
19 struct STRINGLIST *firstdep;
20 };
21
22 /* returns 0 on no find, 1 on find and -1 on error */
checkpath(struct CONTEXT * context,struct NODE * node,const char * path)23 static int checkpath(struct CONTEXT *context, struct NODE *node, const char *path)
24 {
25 struct NODE *depnode;
26
27 /* search up the node and add it if we need */
28 depnode = node_find(context->graph, path);
29 if(depnode)
30 {
31 if(!node_add_dependency_withnode(node, depnode))
32 return -1;
33 return 1;
34 }
35
36 /* check if it exists on the disk */
37 if(file_exist(path))
38 {
39 if(!node_add_dependency(node, path))
40 return -1;
41 return 1;
42 }
43
44 return 0;
45 }
46
47 /* this functions takes the whole deferred lookup list and searches for the file */
do_run(struct CONTEXT * context,struct DEFERRED * info)48 static int do_run(struct CONTEXT *context, struct DEFERRED *info)
49 {
50 struct STRINGLIST *dep;
51 struct STRINGLIST *path;
52 struct DEPPLAIN *plain = (struct DEPPLAIN *)info->user;
53 char buffer[MAX_PATH_LENGTH];
54 int result;
55
56 for(dep = plain->firstdep; dep; dep = dep->next)
57 {
58 /* check the current directory */
59 result = checkpath(context, info->node, dep->str);
60 if(result == 1)
61 continue;
62 if(result == -1)
63 return -1;
64
65 /* check all the other directories */
66 for(path = plain->firstpath; path; path = path->next)
67 {
68 /* build the path, "%s/%s" */
69 if(path_join(path->str, path->len, dep->str, dep->len, buffer, sizeof(buffer)) != 0)
70 return -1;
71
72 result = checkpath(context, info->node, buffer);
73 if(result == 1)
74 break;
75 if(result == -1)
76 return -1;
77 }
78 }
79
80 return 0;
81 }
82
83 /* add_dependency_search(string node, table paths, table deps) */
lf_add_dependency_search(lua_State * L)84 int lf_add_dependency_search(lua_State *L)
85 {
86 struct NODE *node;
87 struct CONTEXT *context;
88 struct DEFERRED *deferred;
89 struct DEPPLAIN *plain;
90
91 if(lua_gettop(L) != 3)
92 luaL_error(L, "add_dep_search: expected 3 arguments");
93 luaL_checktype(L, 1, LUA_TSTRING);
94
95 context = context_get_pointer(L);
96
97 /* check all parameters */
98 node = node_find(context->graph, lua_tostring(L,1));
99 if(!node)
100 luaL_error(L, "add_dep_search: couldn't find node with name '%s'", lua_tostring(L,1));
101 if(lua_type(L,2) != LUA_TTABLE)
102 luaL_error(L, "add_dep_search: expected table as second argument");
103 if(lua_type(L,3) != LUA_TTABLE)
104 luaL_error(L, "add_dep_search: expected table as third argument");
105
106 deferred = (struct DEFERRED *)mem_allocate(context->deferredheap, sizeof(struct DEFERRED));
107 plain = (struct DEPPLAIN *)mem_allocate(context->deferredheap, sizeof(struct DEPPLAIN));
108
109 deferred->node = node;
110 deferred->user = plain;
111 deferred->run = do_run;
112 deferred->next = context->firstdeferred;
113 context->firstdeferred = deferred;
114
115 /* allocate the lookup */
116 plain->firstpath = NULL;
117 plain->firstdep = NULL;
118
119 /* build the string lists */
120 build_stringlist(L, context->deferredheap, &plain->firstpath, 2);
121 build_stringlist(L, context->deferredheap, &plain->firstdep, 3);
122
123 return 0;
124 }
125