find.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly/***********************************************************************
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* This software is part of the ast package *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* Copyright (c) 2003-2011 AT&T Intellectual Property *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* and is licensed under the *
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu* Eclipse Public License, Version 1.0 *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* by AT&T Intellectual Property *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* A copy of the License is available at *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* http://www.eclipse.org/org/documents/epl-v10.html *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* Information and Software Systems Research *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* AT&T Research *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* Florham Park NJ *
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly* Glenn Fowler <gsf@research.att.com> *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly***********************************************************************/
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * jcl file search
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly#define directory(p,s) (stat((p),(s))>=0&&S_ISDIR((s)->st_mode))
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly#define REGULAR(p,s) (stat((p),(s))>=0&&(S_ISREG((s)->st_mode)||streq(p,"/dev/null")))
a9cc955b0a33e631b9ce3404e4e25b62cd067a77Christian Maederstatic struct /* directory list state */
842ae753ab848a8508c4832ab64296b929167a97Christian Maeder Dirlist_t dirs; /* global directory list */
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly * return >0 if path is a regular file
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reillyregular(Jcl_t* jcl, char* path, struct stat* st)
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly register char* s;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register char* t;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder while (*s && !isupper(*s))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder for (s = t + (s - path); *s; s++)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * catch recursive includes
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * expand ${...} in name
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * return expanded value returned in jcl->vp
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * jcl->tp may be clobbered
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reillyexpand(Jcl_t* jcl, const char* name, int flags)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* s;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* t;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register int c;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly for (s = (char*)name; *s; s++)
05cc55892e6c93bdd7b9c3f100ab1bb65fe6a21eLiam O'Reilly if (n = s - (char*)name)
05cc55892e6c93bdd7b9c3f100ab1bb65fe6a21eLiam O'Reilly while (c = *s++)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder while ((c = *s++) && c != '}')
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (t = matched(*v - '0', &n, jcl->disc))
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else if (t = lookup(jcl, v, NiL, flags, DEFAULT))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if ((flags & JCL_SYM_SET) && jcl->vp != jcl->xp)
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else if (((flags & JCL_SYM_EXPORT) || !(flags & JCL_SYM_SET)) && (t = getenv(v)))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return (char*)name;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * append dir to jclfind() include list
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederjclinclude(Jcl_t* jcl, const char* dir, unsigned long flags, Jcldisc_t* disc)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (dir && *(dir = (const char*)expand(jcl, dir, 0)) && !streq(dir, ".") && directory(dir, &st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder for (dp = lp->head; dp; dp = dp->next)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * check the jclinclude() directories
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reillysearch(Jcl_t* jcl, const char* dir, const char* name, unsigned long flags, struct stat* st)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register char* s;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (!dir || !(flags & JCL_STANDARD) || strchr(name, '/'))
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly dp = (jcl = jcl->scope) ? jcl->dirs.head : state.dirs.head;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * return path to name using jclinclude() list
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * path allocated in jcl->vs
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly * !(flags&JCL_STANDARD) checks . and dir of including file
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly * level>0 is not found error message level
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly * { jcl->tp jcl->vp jcl->xp } may be clobbered
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederjclfind(Jcl_t* jcl, const char* name, unsigned long flags, int level, Sfio_t** spp)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* s;
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly if (spp && !(*spp = sfstropen()) || sfstrbuf(*spp, s, strlen(s), 0))
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly name = (const char*)expand(jcl, jclpath(jcl, name), 0);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * check the unadorned path first
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * this handles . and absolute paths
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (s = search(jcl, NiL, name, flags, &st))
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * check the directory of the including file
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * on the assumption that error_info.file is properly stacked
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (!(flags & JCL_STANDARD) && error_info.file && (s = strrchr(error_info.file, '/')))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfprintf(jcl->tp, "%-.*s%s", s - error_info.file + 1, error_info.file, name);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder (*jcl->disc->errorf)(NiL, jcl->disc, ERROR_SYSTEM|level, "%s: not found", name);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (spp && !(*spp = sfopen(NiL, s, "r")) && level > 0 && jcl->disc->errorf)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder (*jcl->disc->errorf)(NiL, jcl->disc, ERROR_SYSTEM|level, "%s: cannot read", s);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder message((-4, "find %s => %s", name, s));