FreeBASIC  0.91.0
file_dir.c
Go to the documentation of this file.
1 /* dir() */
2 
3 #include "../fb.h"
4 #include <dir.h>
5 
6 #define FB_ATTRIB_MASK ~0xFFFFFF00
7 
8 typedef struct {
9  int in_use;
10  int attrib;
11  struct ffblk f;
12 } FB_DIRCTX;
13 
14 static char *find_next ( int *out_attrib )
15 {
16  FB_DIRCTX *ctx = FB_TLSGETCTX( DIR );
17  char *name = NULL;
18 
19  do {
20  if( findnext( &ctx->f ) == 0 ) {
21  name = ctx->f.ff_name;
22  } else {
23  name = NULL;
24  break;
25  }
26  } while( ctx->f.ff_attrib & ~ctx->attrib );
27 
28  *out_attrib = ctx->f.ff_attrib & FB_ATTRIB_MASK;
29  return name;
30 }
31 
32 FBCALL FBSTRING *fb_Dir( FBSTRING *filespec, int attrib, int *out_attrib )
33 {
34  FBSTRING *res;
35  int out_attrib_fake;
36  char *name = NULL;
37  FB_DIRCTX *ctx = FB_TLSGETCTX( DIR );
38  ssize_t len;
39 
40  if( !out_attrib )
41  out_attrib = &out_attrib_fake;
42 
43  len = FB_STRSIZE( filespec );
44 
45  if( len > 0 ) {
46  /* filespec specified (return first result) */
47  ctx->attrib = attrib | 0xFFFFFF00;
48 
49  /* archive bit not set? set the dir bit at least.. */
50  if( (attrib & 0x10) == 0 )
51  ctx->attrib |= 0x20;
52 
53  if( findfirst( filespec->data, &ctx->f, ctx->attrib ) == 0 ) {
54  if( ctx->f.ff_attrib & ~ctx->attrib ) {
55  name = find_next( out_attrib );
56  } else {
57  *out_attrib = ctx->f.ff_attrib & FB_ATTRIB_MASK;
58  name = ctx->f.ff_name;
59  }
60  }
61 
62  if( name ) {
63  ctx->in_use = TRUE;
64  ctx->attrib = attrib;
65  }
66  } else {
67  /* filespec not specified (return next result) */
68  if( ctx->in_use ) {
69  name = find_next( out_attrib );
70  }
71  }
72 
73  /* store filename if found */
74  if( name ) {
75  ctx->in_use = TRUE;
76  len = strlen( name );
77  res = fb_hStrAllocTemp( NULL, len );
78  if( res ) {
79  fb_hStrCopy( res->data, name, len );
80  } else {
81  res = &__fb_ctx.null_desc;
82  }
83  } else {
84  ctx->in_use = FALSE;
85  res = &__fb_ctx.null_desc;
86  *out_attrib = 0;
87  }
88 
89  fb_hStrDelTemp( filespec );
90  return res;
91 }