1 /**
2  * \file   os_pathsearch.c
3  * \brief  Locates a file, given a set of search paths.
4  * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
5  *
6  * \note This function is required by the bootstrapping code; it must be
7  *       implemented here in the host and not scripted.
8  */
9 
10 #include <string.h>
11 #include "premake.h"
12 
13 
os_pathsearch(lua_State * L)14 int os_pathsearch(lua_State* L)
15 {
16 	int i;
17 	for (i = 2; i <= lua_gettop(L); ++i)
18 	{
19 		const char* path;
20 
21 		if (lua_isnil(L, i))
22 			continue;
23 
24 		path = luaL_checkstring(L, i);
25 		do
26 		{
27 			const char* split;
28 
29 			/* look for the closest path separator ; or : */
30 			/* can't use : on windows because it breaks on C:\path */
31 			const char* semi = strchr(path, ';');
32 #if !defined(PLATFORM_WINDOWS)
33 			const char* full = strchr(path, ':');
34 #else
35 			const char* full = NULL;
36 #endif
37 
38 			if (!semi)
39 			{
40 				split = full;
41 			}
42 			else if (!full)
43 			{
44 				split = semi;
45 			}
46 			else
47 			{
48 				split = (semi < full) ? semi : full;
49 			}
50 
51 			/* push this piece of the full search string onto the stack */
52 			if (split)
53 			{
54 				lua_pushlstring(L, path, split - path);
55 			}
56 			else
57 			{
58 				lua_pushstring(L, path);
59 			}
60 
61 			/* keep an extra copy around, so I can return it if I have a match */
62 			lua_pushvalue(L, -1);
63 
64 			/* append the filename to make the full test path */
65 			lua_pushstring(L, "/");
66 			lua_pushvalue(L, 1);
67 			lua_concat(L, 3);
68 
69 			/* test it - if it exists return the path */
70 			if (do_isfile(lua_tostring(L, -1)))
71 			{
72 				lua_pop(L, 1);
73 				return 1;
74 			}
75 
76 			/* no match, set up the next try */
77 			lua_pop(L, 2);
78 			path = (split) ? split + 1 : NULL;
79 		}
80 		while (path);
81 	}
82 
83 	return 0;
84 }
85