1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2011 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
19*b30d1939SAndy Fiddaman * Phong Vo <kpv@research.att.com> *
20*b30d1939SAndy Fiddaman * *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman /*
24*b30d1939SAndy Fiddaman * Glenn Fowler
25*b30d1939SAndy Fiddaman * AT&T Research
26*b30d1939SAndy Fiddaman *
27*b30d1939SAndy Fiddaman * include style search support
28*b30d1939SAndy Fiddaman */
29*b30d1939SAndy Fiddaman
30*b30d1939SAndy Fiddaman #include <ast.h>
31*b30d1939SAndy Fiddaman #include <error.h>
32*b30d1939SAndy Fiddaman #include <ls.h>
33*b30d1939SAndy Fiddaman
34*b30d1939SAndy Fiddaman #define directory(p,s) (stat((p),(s))>=0&&S_ISDIR((s)->st_mode))
35*b30d1939SAndy Fiddaman #define regular(p,s) (stat((p),(s))>=0&&(S_ISREG((s)->st_mode)||streq(p,"/dev/null")))
36*b30d1939SAndy Fiddaman
37*b30d1939SAndy Fiddaman typedef struct Dir_s /* directory list element */
38*b30d1939SAndy Fiddaman {
39*b30d1939SAndy Fiddaman struct Dir_s* next; /* next in list */
40*b30d1939SAndy Fiddaman char dir[1]; /* directory path */
41*b30d1939SAndy Fiddaman } Dir_t;
42*b30d1939SAndy Fiddaman
43*b30d1939SAndy Fiddaman static struct /* directory list state */
44*b30d1939SAndy Fiddaman {
45*b30d1939SAndy Fiddaman Dir_t* head; /* directory list head */
46*b30d1939SAndy Fiddaman Dir_t* tail; /* directory list tail */
47*b30d1939SAndy Fiddaman } state;
48*b30d1939SAndy Fiddaman
49*b30d1939SAndy Fiddaman /*
50*b30d1939SAndy Fiddaman * append dir to pathfind() include list
51*b30d1939SAndy Fiddaman */
52*b30d1939SAndy Fiddaman
53*b30d1939SAndy Fiddaman int
pathinclude(const char * dir)54*b30d1939SAndy Fiddaman pathinclude(const char* dir)
55*b30d1939SAndy Fiddaman {
56*b30d1939SAndy Fiddaman register Dir_t* dp;
57*b30d1939SAndy Fiddaman struct stat st;
58*b30d1939SAndy Fiddaman
59*b30d1939SAndy Fiddaman if (dir && *dir && !streq(dir, ".") && directory(dir, &st))
60*b30d1939SAndy Fiddaman {
61*b30d1939SAndy Fiddaman for (dp = state.head; dp; dp = dp->next)
62*b30d1939SAndy Fiddaman if (streq(dir, dp->dir))
63*b30d1939SAndy Fiddaman return 0;
64*b30d1939SAndy Fiddaman if (!(dp = oldof(0, Dir_t, 1, strlen(dir))))
65*b30d1939SAndy Fiddaman return -1;
66*b30d1939SAndy Fiddaman strcpy(dp->dir, dir);
67*b30d1939SAndy Fiddaman dp->next = 0;
68*b30d1939SAndy Fiddaman if (state.tail)
69*b30d1939SAndy Fiddaman state.tail = state.tail->next = dp;
70*b30d1939SAndy Fiddaman else
71*b30d1939SAndy Fiddaman state.head = state.tail = dp;
72*b30d1939SAndy Fiddaman }
73*b30d1939SAndy Fiddaman return 0;
74*b30d1939SAndy Fiddaman }
75*b30d1939SAndy Fiddaman
76*b30d1939SAndy Fiddaman /*
77*b30d1939SAndy Fiddaman * return path to name using pathinclude() list
78*b30d1939SAndy Fiddaman * path placed in <buf,size>
79*b30d1939SAndy Fiddaman * if lib!=0 then pathpath() attempted after include search
80*b30d1939SAndy Fiddaman * if type!=0 and name has no '.' then file.type also attempted
81*b30d1939SAndy Fiddaman * any *: prefix in lib is ignored (discipline library dictionary support)
82*b30d1939SAndy Fiddaman */
83*b30d1939SAndy Fiddaman
84*b30d1939SAndy Fiddaman char*
pathfind(const char * name,const char * lib,const char * type,char * buf,size_t size)85*b30d1939SAndy Fiddaman pathfind(const char* name, const char* lib, const char* type, char* buf, size_t size)
86*b30d1939SAndy Fiddaman {
87*b30d1939SAndy Fiddaman register Dir_t* dp;
88*b30d1939SAndy Fiddaman register char* s;
89*b30d1939SAndy Fiddaman char tmp[PATH_MAX];
90*b30d1939SAndy Fiddaman struct stat st;
91*b30d1939SAndy Fiddaman
92*b30d1939SAndy Fiddaman if (((s = strrchr(name, '/')) || (s = (char*)name)) && strchr(s, '.'))
93*b30d1939SAndy Fiddaman type = 0;
94*b30d1939SAndy Fiddaman
95*b30d1939SAndy Fiddaman /*
96*b30d1939SAndy Fiddaman * always check the unadorned path first
97*b30d1939SAndy Fiddaman * this handles . and absolute paths
98*b30d1939SAndy Fiddaman */
99*b30d1939SAndy Fiddaman
100*b30d1939SAndy Fiddaman if (regular(name, &st))
101*b30d1939SAndy Fiddaman {
102*b30d1939SAndy Fiddaman strncopy(buf, name, size);
103*b30d1939SAndy Fiddaman return buf;
104*b30d1939SAndy Fiddaman }
105*b30d1939SAndy Fiddaman if (type)
106*b30d1939SAndy Fiddaman {
107*b30d1939SAndy Fiddaman sfsprintf(buf, size, "%s.%s", name, type);
108*b30d1939SAndy Fiddaman if (regular(buf, &st))
109*b30d1939SAndy Fiddaman return buf;
110*b30d1939SAndy Fiddaman }
111*b30d1939SAndy Fiddaman if (*name == '/')
112*b30d1939SAndy Fiddaman return 0;
113*b30d1939SAndy Fiddaman
114*b30d1939SAndy Fiddaman /*
115*b30d1939SAndy Fiddaman * check the directory of the including file
116*b30d1939SAndy Fiddaman * on the assumption that error_info.file is properly stacked
117*b30d1939SAndy Fiddaman */
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman if (error_info.file && (s = strrchr(error_info.file, '/')))
120*b30d1939SAndy Fiddaman {
121*b30d1939SAndy Fiddaman sfsprintf(buf, size, "%-.*s%s", s - error_info.file + 1, error_info.file, name);
122*b30d1939SAndy Fiddaman if (regular(buf, &st))
123*b30d1939SAndy Fiddaman return buf;
124*b30d1939SAndy Fiddaman if (type)
125*b30d1939SAndy Fiddaman {
126*b30d1939SAndy Fiddaman sfsprintf(buf, size, "%-.*s%s%.s", s - error_info.file + 1, error_info.file, name, type);
127*b30d1939SAndy Fiddaman if (regular(buf, &st))
128*b30d1939SAndy Fiddaman return buf;
129*b30d1939SAndy Fiddaman }
130*b30d1939SAndy Fiddaman }
131*b30d1939SAndy Fiddaman
132*b30d1939SAndy Fiddaman /*
133*b30d1939SAndy Fiddaman * check the include dir list
134*b30d1939SAndy Fiddaman */
135*b30d1939SAndy Fiddaman
136*b30d1939SAndy Fiddaman for (dp = state.head; dp; dp = dp->next)
137*b30d1939SAndy Fiddaman {
138*b30d1939SAndy Fiddaman sfsprintf(tmp, sizeof(tmp), "%s/%s", dp->dir, name);
139*b30d1939SAndy Fiddaman if (pathpath(tmp, "", PATH_REGULAR, buf, size))
140*b30d1939SAndy Fiddaman return buf;
141*b30d1939SAndy Fiddaman if (type)
142*b30d1939SAndy Fiddaman {
143*b30d1939SAndy Fiddaman sfsprintf(tmp, sizeof(tmp), "%s/%s.%s", dp->dir, name, type);
144*b30d1939SAndy Fiddaman if (pathpath(tmp, "", PATH_REGULAR, buf, size))
145*b30d1939SAndy Fiddaman return buf;
146*b30d1939SAndy Fiddaman }
147*b30d1939SAndy Fiddaman }
148*b30d1939SAndy Fiddaman
149*b30d1939SAndy Fiddaman /*
150*b30d1939SAndy Fiddaman * finally a lib related search on PATH
151*b30d1939SAndy Fiddaman */
152*b30d1939SAndy Fiddaman
153*b30d1939SAndy Fiddaman if (lib)
154*b30d1939SAndy Fiddaman {
155*b30d1939SAndy Fiddaman if (s = strrchr((char*)lib, ':'))
156*b30d1939SAndy Fiddaman lib = (const char*)s + 1;
157*b30d1939SAndy Fiddaman sfsprintf(tmp, sizeof(tmp), "lib/%s/%s", lib, name);
158*b30d1939SAndy Fiddaman if (pathpath(tmp, "", PATH_REGULAR, buf, size))
159*b30d1939SAndy Fiddaman return buf;
160*b30d1939SAndy Fiddaman if (type)
161*b30d1939SAndy Fiddaman {
162*b30d1939SAndy Fiddaman sfsprintf(tmp, sizeof(tmp), "lib/%s/%s.%s", lib, name, type);
163*b30d1939SAndy Fiddaman if (pathpath(tmp, "", PATH_REGULAR, buf, size))
164*b30d1939SAndy Fiddaman return buf;
165*b30d1939SAndy Fiddaman }
166*b30d1939SAndy Fiddaman }
167*b30d1939SAndy Fiddaman return 0;
168*b30d1939SAndy Fiddaman }
169