mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 11:51:27 +00:00
Add dentfill() and dentfree()
This commit is contained in:
parent
5335be5832
commit
32bce991be
70
noice.c
70
noice.c
|
@ -441,6 +441,46 @@ printent(struct entry *ent, int active)
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dentfill(DIR *dirp, struct entry **dents,
|
||||||
|
int (*filter)(regex_t *, char *), regex_t *re)
|
||||||
|
{
|
||||||
|
struct dirent *dp;
|
||||||
|
struct stat sb;
|
||||||
|
int n = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
|
/* Skip self and parent */
|
||||||
|
if (strcmp(dp->d_name, ".") == 0
|
||||||
|
|| strcmp(dp->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
if (filter(re, dp->d_name) == 0)
|
||||||
|
continue;
|
||||||
|
*dents = xrealloc(*dents, (n + 1) * sizeof(**dents));
|
||||||
|
(*dents)[n].name = xstrdup(dp->d_name);
|
||||||
|
/* Get mode flags */
|
||||||
|
r = fstatat(dirfd(dirp), dp->d_name, &sb,
|
||||||
|
AT_SYMLINK_NOFOLLOW);
|
||||||
|
if (r == -1)
|
||||||
|
printerr(1, "stat");
|
||||||
|
(*dents)[n].mode = sb.st_mode;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dentfree(struct entry *dents, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
free(dents[i].name);
|
||||||
|
free(dents);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
browse(const char *ipath, const char *ifilter)
|
browse(const char *ipath, const char *ifilter)
|
||||||
{
|
{
|
||||||
|
@ -476,31 +516,7 @@ begin:
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto nochange;
|
goto nochange;
|
||||||
|
|
||||||
while ((dp = readdir(dirp)) != NULL) {
|
n = dentfill(dirp, &dents, visible, &filter_re);
|
||||||
char *name;
|
|
||||||
|
|
||||||
/* Skip self and parent */
|
|
||||||
if (strcmp(dp->d_name, ".") == 0
|
|
||||||
|| strcmp(dp->d_name, "..") == 0)
|
|
||||||
continue;
|
|
||||||
if (!visible(&filter_re, dp->d_name))
|
|
||||||
continue;
|
|
||||||
/* Deep copy because readdir(3) reuses the entries */
|
|
||||||
dents = xrealloc(dents, (n + 1) * sizeof(*dents));
|
|
||||||
dents[n].name = xstrdup(dp->d_name);
|
|
||||||
/* Handle root case */
|
|
||||||
if (strcmp(path, "/") == 0)
|
|
||||||
asprintf(&name, "/%s", dents[n].name);
|
|
||||||
else
|
|
||||||
asprintf(&name, "%s/%s", path, dents[n].name);
|
|
||||||
/* Get mode flags */
|
|
||||||
r = lstat(name, &sb);
|
|
||||||
free(name);
|
|
||||||
if (r == -1)
|
|
||||||
printerr(1, "stat");
|
|
||||||
dents[n].mode = sb.st_mode;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure cur is in range */
|
/* Make sure cur is in range */
|
||||||
cur = MIN(cur, n - 1);
|
cur = MIN(cur, n - 1);
|
||||||
|
@ -695,9 +711,7 @@ nochange:
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for (i = 0; i < n; i++)
|
dentfree(dents, n);
|
||||||
free(dents[i].name);
|
|
||||||
free(dents);
|
|
||||||
|
|
||||||
/* Should never be null */
|
/* Should never be null */
|
||||||
r = closedir(dirp);
|
r = closedir(dirp);
|
||||||
|
|
Loading…
Reference in a new issue