find.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly/***********************************************************************
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner* *
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* *
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* *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* Information and Software Systems Research *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* AT&T Research *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* Florham Park NJ *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly* *
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly* Glenn Fowler <gsf@research.att.com> *
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly* *
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly***********************************************************************/
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly#pragma prototyped
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly/*
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * jcl file search
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly */
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reilly
842ae753ab848a8508c4832ab64296b929167a97Christian Maeder#include "jcllib.h"
abc67c4b359c4a5bb953c6d55fb0f9133369d707Liam O'Reilly
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly#include <ctype.h>
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly#include <ls.h>
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly
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")))
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly
a9cc955b0a33e631b9ce3404e4e25b62cd067a77Christian Maederstatic struct /* directory list state */
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reilly{
842ae753ab848a8508c4832ab64296b929167a97Christian Maeder Dirlist_t dirs; /* global directory list */
842ae753ab848a8508c4832ab64296b929167a97Christian Maeder} state;
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly/*
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly * return >0 if path is a regular file
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly */
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reillystatic int
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reillyregular(Jcl_t* jcl, char* path, struct stat* st)
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly{
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly register char* s;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register char* t;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register Include_t* ip;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (REGULAR(path, st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder goto found;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (s = strrchr(path, '/'))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder s++;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly else
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder s = path;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder while (*s && !isupper(*s))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s++;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (*s)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly t = sfprints("%s", path);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder for (s = t + (s - path); *s; s++)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (isupper(*s))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly *s = tolower(*s);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (REGULAR(t, st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly strcpy(path, t);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly goto found;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return 0;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly found:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /*
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * catch recursive includes
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly */
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly do
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly for (ip = jcl->include; ip; ip = ip->prev)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (streq(path, ip->path))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return 0;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder } while (jcl = jcl->scope);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return 1;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder}
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly/*
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'Reilly */
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
9aeda2b3ae8ce0b018955521e4ca835a8ba8a27bLiam O'Reillychar*
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reillyexpand(Jcl_t* jcl, const char* name, int flags)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* s;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* t;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register int c;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder char* b;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder char* v;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly size_t n;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly size_t p;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly Sfio_t* vp;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly if (jcl)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly for (s = (char*)name; *s; s++)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (*s == '$' && *(s + 1) == '{')
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly p = sfstrtell(jcl->tp);
05cc55892e6c93bdd7b9c3f100ab1bb65fe6a21eLiam O'Reilly if (n = s - (char*)name)
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly sfwrite(jcl->tp, name, n);
05cc55892e6c93bdd7b9c3f100ab1bb65fe6a21eLiam O'Reilly while (c = *s++)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (c == '$' && *s == '{')
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder b = s;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder n = sfstrtell(jcl->tp);
9aeda2b3ae8ce0b018955521e4ca835a8ba8a27bLiam O'Reilly s++;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (*s == '%' && *(s + 1) == '%')
abc67c4b359c4a5bb953c6d55fb0f9133369d707Liam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s += 2;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly sfputr(jcl->tp, JCL_AUTO, -1);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder while ((c = *s++) && c != '}')
abc67c4b359c4a5bb953c6d55fb0f9133369d707Liam O'Reilly sfputc(jcl->tp, c);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfputc(jcl->tp, 0);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly v = sfstrseek(jcl->tp, n, SEEK_SET);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (isdigit(*v) && !*(v + 1))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (t = matched(*v - '0', &n, jcl->disc))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfwrite(jcl->tp, t, n);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly }
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else if (t = lookup(jcl, v, NiL, flags, DEFAULT))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if ((flags & JCL_SYM_SET) && jcl->vp != jcl->xp)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly vp = jcl->vp;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder jcl->vp = jcl->xp;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly t = expand(jcl, t, flags);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfputr(jcl->tp, t, -1);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder jcl->vp = vp;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly sfputr(jcl->tp, t, -1);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly }
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else if (((flags & JCL_SYM_EXPORT) || !(flags & JCL_SYM_SET)) && (t = getenv(v)))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly sfputr(jcl->tp, t, -1);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly else if (flags & JCL_SYM_SET)
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly sfputc(jcl->tp, '$');
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s = b;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly else
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly sfputc(jcl->tp, c);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly sfputc(jcl->tp, 0);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s = sfstrseek(jcl->tp, p, SEEK_SET);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly message((-7, "expand %s => %s", name, s));
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly sfputr(jcl->vp, s, -1);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (!(s = sfstruse(jcl->vp)))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly nospace(jcl, NiL);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly return s;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return (char*)name;
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly}
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly/*
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * append dir to jclfind() include list
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly */
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reillyint
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederjclinclude(Jcl_t* jcl, const char* dir, unsigned long flags, Jcldisc_t* disc)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly register Dirlist_t* lp;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register Dir_t* dp;
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly struct stat st;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (dir && *(dir = (const char*)expand(jcl, dir, 0)) && !streq(dir, ".") && directory(dir, &st))
dd7da1b5fedc05b92ba023ebd803e6f4a662503bChristian Maeder {
dd7da1b5fedc05b92ba023ebd803e6f4a662503bChristian Maeder lp = jcl ? &jcl->dirs : &state.dirs;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder for (dp = lp->head; dp; dp = dp->next)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (streq(dir, dp->dir))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return 0;
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly if (!(dp = oldof(0, Dir_t, 1, strlen(dir))))
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly {
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly nospace(jcl, disc);
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly return -1;
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly strcpy(dp->dir, dir);
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly dp->next = 0;
d9c1248c7972dfdafbacb1b73b2eb965eac9ef42Liam O'Reilly dp->flags = flags;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (lp->tail)
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly lp->tail = lp->tail->next = dp;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder else
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder lp->head = lp->tail = dp;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return 0;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder}
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder/*
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * check the jclinclude() directories
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly */
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reillystatic char*
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reillysearch(Jcl_t* jcl, const char* dir, const char* name, unsigned long flags, struct stat* st)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly{
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register char* s;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly register Dir_t* dp;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly Jcl_t* top;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (!dir || !(flags & JCL_STANDARD) || strchr(name, '/'))
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly {
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (dir && *name != '/')
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly sfprintf(jcl->tp, "%s/", dir);
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly sfprintf(jcl->vp, "%s", name);
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (!(s = sfstruse(jcl->vp)))
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly nospace(jcl, NiL);
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (regular(jcl, s, st))
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly return s;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly }
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (*name != '/')
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly {
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly top = jcl;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly dp = jcl->dirs.head;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly for (;;)
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly {
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly for (; dp; dp = dp->next)
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (flags & dp->flags)
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly {
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (dir && *dp->dir != '/')
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly sfprintf(top->tp, "%s/", dir);
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly sfprintf(top->tp, "%s/%s", dp->dir, name);
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (!(s = sfstruse(top->tp)))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder nospace(jcl, NiL);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (regular(top, s, st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return s;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly }
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly if (!jcl)
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly break;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly dp = (jcl = jcl->scope) ? jcl->dirs.head : state.dirs.head;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly }
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly }
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly return 0;
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly}
9e5f4073e948104307d43c3962d624b8416f191fLiam O'Reilly
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder/*
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
22ebb9b9649c48a21572cbaed8d7f4b8428af893Christian Maeder */
22ebb9b9649c48a21572cbaed8d7f4b8428af893Christian Maeder
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reillychar*
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederjclfind(Jcl_t* jcl, const char* name, unsigned long flags, int level, Sfio_t** spp)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder register char* s;
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reilly struct stat st;
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reilly
9738b4e358f960105062839c835bb9eff3e44588Liam O'Reilly if (flags & JCL_PROC)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfprintf(jcl->vp, "(PROC)%s", name);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (!(s = sfstruse(jcl->vp)))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly nospace(jcl, NiL);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (s = lookup(jcl, s, NiL, 0, 0))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
7db74d99f2d2705558510202067b91aca1912f6fLiam O'Reilly if (spp && !(*spp = sfstropen()) || sfstrbuf(*spp, s, strlen(s), 0))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (*spp)
33bdce26495121cdbce30331ef90a1969126a840Liam O'Reilly sfclose(*spp);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly nospace(jcl, NiL);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return 0;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s = (char*)name;
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly goto save;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
c3efd4f435e954846981cf46bca64e0485266634Liam O'Reilly name = (const char*)expand(jcl, jclpath(jcl, name), 0);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /*
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * check the unadorned path first
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * this handles . and absolute paths
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (s = search(jcl, NiL, name, flags, &st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder goto found;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (*name != '/')
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly /*
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly * check the directory of the including file
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly * on the assumption that error_info.file is properly stacked
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (!(flags & JCL_STANDARD) && error_info.file && (s = strrchr(error_info.file, '/')))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sfprintf(jcl->tp, "%-.*s%s", s - error_info.file + 1, error_info.file, name);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly if (!(s = sfstruse(jcl->tp)))
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly nospace(jcl, NiL);
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly if (regular(jcl, s, &st))
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder goto found;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly }
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (flags & JCL_CREATE)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly {
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly if (spp)
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly *spp = 0;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly s = (char*)name;
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly goto save;
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly }
0e51f08fb6ced8e6a9e69eb5976fcc20dbf07019Liam O'Reilly if (level && jcl->disc->errorf)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder (*jcl->disc->errorf)(NiL, jcl->disc, ERROR_SYSTEM|level, "%s: not found", name);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return 0;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder found:
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));
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly save:
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly return stash(jcl, jcl->vs, s, 0);
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly}
d3b4ad111a281d125659e12d6641943f29d6b3dfLiam O'Reilly