Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/misc/ftwalk.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
/*
24
* Glenn Fowler
25
* AT&T Research
26
*
27
* ftwalk on top of fts
28
*/
29
30
#include <ast.h>
31
#include <ftwalk.h>
32
33
static struct
34
{
35
int (*comparf)(Ftw_t*, Ftw_t*);
36
} state;
37
38
/*
39
* why does fts take FTSENT** instead of FTSENT*
40
*/
41
42
static int
43
ftscompare(Ftw_t* const* pf1, Ftw_t* const* pf2)
44
{
45
return (*state.comparf)(*pf1, *pf2);
46
}
47
48
/*
49
* the real thing -- well it used to be
50
*/
51
52
int
53
ftwalk(const char* path, int (*userf)(Ftw_t*), int flags, int (*comparf)(Ftw_t*, Ftw_t*))
54
{
55
register FTS* f;
56
register FTSENT* e;
57
register int children;
58
register int rv;
59
int oi;
60
int ns;
61
int os;
62
int nd;
63
FTSENT* x;
64
FTSENT* dd[2];
65
66
flags ^= FTS_ONEPATH;
67
if (flags & FTW_TWICE)
68
flags &= ~(FTS_NOPREORDER|FTS_NOPOSTORDER);
69
else if (flags & FTW_POST)
70
flags |= FTS_NOPREORDER;
71
else
72
flags |= FTS_NOPOSTORDER;
73
if (children = flags & FTW_CHILDREN)
74
flags |= FTS_SEEDOT;
75
state.comparf = comparf;
76
if (!(f = fts_open((char* const*)path, flags, comparf ? ftscompare : 0)))
77
{
78
if (!path || !(flags & FTS_ONEPATH) && !(path = (const char*)(*((char**)path))))
79
return -1;
80
ns = strlen(path) + 1;
81
if (!(e = newof(0, FTSENT, 1, ns)))
82
return -1;
83
e->fts_accpath = e->fts_name = e->fts_path = strcpy((char*)(e + 1), path);
84
e->fts_namelen = e->fts_pathlen = ns;
85
e->fts_info = FTS_NS;
86
e->parent = e;
87
e->parent->link = e;
88
rv = (*userf)((Ftw_t*)e);
89
free(e);
90
return rv;
91
}
92
rv = 0;
93
if (children && (e = fts_children(f, 0)))
94
{
95
nd = 0;
96
for (x = e; x; x = x->link)
97
if (x->info & FTS_DD)
98
{
99
x->statb = *x->fts_statp;
100
x->info &= ~FTS_DD;
101
dd[nd++] = x;
102
if (nd >= elementsof(dd))
103
break;
104
}
105
e->parent->link = e;
106
rv = (*userf)((Ftw_t*)e->parent);
107
e->parent->link = 0;
108
while (nd > 0)
109
dd[--nd]->info |= FTS_DD;
110
for (x = e; x; x = x->link)
111
if (!(x->info & FTS_D))
112
x->status = FTS_SKIP;
113
}
114
while (!rv && (e = fts_read(f)))
115
{
116
oi = e->info;
117
os = e->status;
118
ns = e->status = e->path == e->fts_accpath ? FTW_PATH : FTW_NAME;
119
nd = 0;
120
switch (e->info)
121
{
122
case FTS_D:
123
case FTS_DNX:
124
if (children)
125
for (x = fts_children(f, 0); x; x = x->link)
126
if (x->info & FTS_DD)
127
{
128
x->statb = *x->fts_statp;
129
x->info &= ~FTS_DD;
130
dd[nd++] = x;
131
if (nd >= elementsof(dd))
132
break;
133
}
134
break;
135
case FTS_DOT:
136
continue;
137
case FTS_ERR:
138
e->info = FTS_NS;
139
break;
140
case FTS_NSOK:
141
e->info = FTS_NSOK;
142
break;
143
case FTS_SLNONE:
144
e->info = FTS_SL;
145
break;
146
}
147
rv = (*userf)((Ftw_t*)e);
148
e->info = oi;
149
if (e->status == ns)
150
e->status = os;
151
while (nd > 0)
152
dd[--nd]->info |= FTS_DD;
153
}
154
fts_close(f);
155
return rv;
156
}
157
158