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