📄 crdir.c
字号:
/*
CRDIR.C
compatible recursive directory search
*/
#include <stdlib.h>
#include <string.h>
#include "ccommon.h"
#include "crdir.h"
#ifdef C_DOS
#include <direct.h>
#endif
static char *_c_delimiter_to_host(char *s)
{
static char t[CRDIR_MAX_PATHNAME];
int i = 0;
while( i < CRDIR_MAX_PATHNAME)
{
t[i] = s[i];
#ifdef C_UNIX
if ( t[i] == '\\' )
t[i] = C_DELIMITER_CHAR;
#endif
#ifdef C_DOS
if ( t[i] == '/' )
t[i] = C_DELIMITER_CHAR;
#endif
if ( t[i] == '\0' )
break;
i++;
}
t[CRDIR_MAX_PATHNAME-1] = '\0';
return t;
}
CRDIR *c_openrdir(char *dir, char *pat, int options)
{
CRDIR *crd;
crd = (CRDIR *)malloc(sizeof(struct _CRDIR_struct));
if ( crd != NULL )
{
c_set_path(dir);
crd->cdir_depth = 0;
crd->options = options;
c_strncpy(crd->pat, pat, CRDIR_MAX_FILE);
if ( (options & CRDIR_REL_PATH) == 0 )
{
c_strncpy(crd->pn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
c_strncpy(crd->spn, _c_delimiter_to_host(dir), CRDIR_MAX_PATHNAME);
if ( crd->pn[0] == '\0' )
strcpy(crd->pn, _c_delimiter_to_host("./"));
if ( crd->spn[0] == '\0' )
strcpy(crd->spn, _c_delimiter_to_host("./"));
if ( strcmp( crd->pn+strlen(crd->pn)-1, _c_delimiter_to_host("/")) != 0 )
strcat(crd->pn, _c_delimiter_to_host("/"));
if ( strcmp( crd->spn+strlen(crd->spn)-1, _c_delimiter_to_host("/")) != 0 )
strcat(crd->spn, _c_delimiter_to_host("/"));
}
else
{
strcpy(crd->pn, _c_delimiter_to_host("./"));
strcpy(crd->spn, _c_delimiter_to_host("./"));
}
crd->pn_end_pos[crd->cdir_depth] = strlen(crd->pn);
crd->spn_end_pos[crd->cdir_depth] = strlen(crd->spn);
crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
if ( crd->cdir_list[crd->cdir_depth] != NULL )
{
crd->cdir_depth++;
crd->mem_dir = NULL;
return crd;
}
free(crd);
}
return NULL;
}
static int _c_push_rdir(CRDIR *crd, char *name, char *sname, int is_dir)
{
size_t pn_len, spn_len, name_len, sname_len;
pn_len = strlen(crd->pn);
spn_len = strlen(crd->spn);
name_len = strlen(name);
sname_len = strlen(sname);
if ( spn_len+sname_len+2 >= CRDIR_MAX_PATHNAME )
return 0;
if ( crd->cdir_depth >= CRDIR_MAX_DEPTH )
return 0;
if ( crd->cdir_depth == 0 )
return 0;
strcpy(crd->pn+pn_len, name);
strcpy(crd->spn+spn_len, sname);
strcpy(crd->pn+pn_len+name_len, _c_delimiter_to_host("/"));
strcpy(crd->spn+spn_len+sname_len, _c_delimiter_to_host("/"));
crd->pn_end_pos[crd->cdir_depth] = pn_len+name_len+1;
crd->spn_end_pos[crd->cdir_depth] = spn_len+sname_len+1;
crd->cdir_list[crd->cdir_depth] = NULL;
if ( is_dir != 0 )
{
if ( c_chdir(name) != 0 )
{
crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
crd->spn[crd->spn_end_pos[crd->cdir_depth-1]] = '\0';
/* printf("c_chdir(%s) failed\n", name); */
return 0;
}
crd->cdir_list[crd->cdir_depth] = c_opendir(".", crd->pat, crd->options);
if ( crd->cdir_list[crd->cdir_depth] == NULL )
{
crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
crd->spn[crd->spn_end_pos[crd->cdir_depth-1]] = '\0';
/* printf("opendir() failed\n"); */
return 0;
}
}
crd->cdir_depth++;
return 1;
}
static int _c_pop_rdir(CRDIR *crd)
{
if ( crd->cdir_depth == 0 )
return 0;
crd->cdir_depth--;
if ( crd->cdir_list[crd->cdir_depth] != NULL )
{
c_closedir(crd->cdir_list[crd->cdir_depth]);
if ( crd->cdir_depth != 0 )
{
c_chdir("..");
}
}
crd->pn[crd->pn_end_pos[crd->cdir_depth-1]] = '\0';
crd->spn[crd->spn_end_pos[crd->cdir_depth-1]] = '\0';
return 1;
}
struct c_dirent *c_readrdir(CRDIR *crd)
{
size_t pos;
struct c_dirent *de;
if ( crd->cdir_depth == 0 )
return NULL;
if ( (crd->options & CRDIR_GO_DIRS) != 0 )
{
for(;;)
{
if ( crd->cdir_depth == 0 )
return NULL;
pos = crd->cdir_depth-1;
if ( crd->mem_dir != NULL )
{
de = crd->mem_dir;
crd->mem_dir = NULL;
_c_push_rdir(crd, c_get_name(de), c_get_short_name(de), 1);
continue; /* return c_readrdir(crd); */
}
de = c_readdir(crd->cdir_list[pos]);
if ( de != NULL )
{
if ( c_is_dir(de) != 0 )
{
if ( strcmp(c_get_name(de),".") == 0 )
continue; /* return c_readrdir(crd); */
if ( strcmp(c_get_name(de),"..") == 0 )
continue; /* return c_readrdir(crd); */
if ( (crd->options & CRDIR_RET_DIRS) != 0 )
{
crd->mem_dir = de;
return de;
}
_c_push_rdir(crd, c_get_name(de), c_get_short_name(de), 1);
continue; /* return c_readrdir(crd); */
}
return de;
}
if ( _c_pop_rdir(crd) != 0 )
{
/* return c_readrdir(crd); */
continue;
}
else
break;
}
}
else
{
pos = crd->cdir_depth-1;
for(;;)
{
de = c_readdir(crd->cdir_list[pos]);
if ( de == NULL )
break;
if ( c_is_dir(de) != 0 )
{
if ( (crd->options & CRDIR_RET_DIRS) != 0 )
return de;
}
else
{
return de;
}
}
}
return NULL;
}
void c_closerdir(CRDIR *crd)
{
if ( crd == NULL )
return;
while( _c_pop_rdir(crd) != 0 )
;
free(crd);
}
#ifdef CRDIR_MAIN
#include <stdio.h>
void main(void)
{
CRDIR *d;
struct c_dirent *e;
d = c_openrdir(".", "*.exe", CRDIR_DEFAULT);
for(;;)
{
e = c_readrdir(d);
if ( e == NULL )
break;
printf("%d %s %-14s %s\n", d->cdir_depth, d->pn, e->d_short_name, e->d_name);
}
c_closerdir(d);
c_io_clear();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -