github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/dirent.h (about)

     1  /****************************************************************************
     2  
     3      Declaration of POSIX directory browsing functions and types for Win32.
     4  
     5      Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
     6      History: Created March 1997. Updated June 2003.
     7               Reviewed by Ramon Santamaria for raylib on January 2020.
     8  
     9      Copyright Kevlin Henney, 1997, 2003. All rights reserved.
    10  
    11      Permission to use, copy, modify, and distribute this software and its
    12      documentation for any purpose is hereby granted without fee, provided
    13      that this copyright and permissions notice appear in all copies and
    14      derivatives.
    15      
    16      This software is supplied "as is" without express or implied warranty.
    17  
    18      But that said, if there are any problems please get in touch.
    19  
    20  ****************************************************************************/
    21  
    22  #ifndef DIRENT_H
    23  #define DIRENT_H
    24  
    25  // Allow custom memory allocators
    26  #ifndef DIRENT_MALLOC
    27      #define DIRENT_MALLOC(sz)   malloc(sz)
    28  #endif
    29  #ifndef DIRENT_FREE
    30      #define DIRENT_FREE(p)      free(p)
    31  #endif
    32  
    33  //----------------------------------------------------------------------------------
    34  // Types and Structures Definition
    35  //----------------------------------------------------------------------------------
    36  
    37  // Fordward declaration of DIR, implementation below
    38  typedef struct DIR DIR;
    39  
    40  struct dirent {
    41      char *d_name;
    42  };
    43  
    44  #ifdef __cplusplus
    45  extern "C" {
    46  #endif
    47  
    48  //------------------------------------------------------------------------------------
    49  // Functions Declaration
    50  //------------------------------------------------------------------------------------
    51  DIR *opendir(const char *name);
    52  int closedir(DIR *dir);
    53  struct dirent *readdir(DIR *dir);
    54  void rewinddir(DIR *dir);
    55  
    56  #ifdef __cplusplus
    57  }
    58  #endif
    59  
    60  #endif      // DIRENT_H
    61  
    62  /****************************************************************************
    63  
    64      Implementation of POSIX directory browsing functions and types for Win32.
    65  
    66      Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
    67      History: Created March 1997. Updated June 2003.
    68               Reviewed by Ramon Santamaria for raylib on January 2020.
    69  
    70      Copyright Kevlin Henney, 1997, 2003. All rights reserved.
    71  
    72      Permission to use, copy, modify, and distribute this software and its
    73      documentation for any purpose is hereby granted without fee, provided
    74      that this copyright and permissions notice appear in all copies and
    75      derivatives.
    76      
    77      This software is supplied "as is" without express or implied warranty.
    78  
    79      But that said, if there are any problems please get in touch.
    80  
    81  ****************************************************************************/
    82  
    83  #include <io.h>         // _findfirst and _findnext set errno iff they return -1
    84  #include <stdlib.h>
    85  #include <string.h>
    86  #include <errno.h>
    87  
    88  //----------------------------------------------------------------------------------
    89  // Types and Structures Definition
    90  //----------------------------------------------------------------------------------
    91  typedef ptrdiff_t handle_type;  // C99's intptr_t not sufficiently portable
    92  
    93  struct DIR {
    94      handle_type handle;         // -1 for failed rewind
    95      struct _finddata_t info;
    96      struct dirent result;       // d_name null iff first time
    97      char *name;                 // null-terminated char string
    98  };
    99  
   100  DIR *opendir(const char *name)
   101  {
   102      DIR *dir = 0;
   103  
   104      if (name && name[0])
   105      {
   106          size_t base_length = strlen(name);
   107          
   108          // Search pattern must end with suitable wildcard
   109          const char *all = strchr("/\\", name[base_length - 1]) ? "*" : "/*";
   110  
   111          if ((dir = (DIR *)DIRENT_MALLOC(sizeof *dir)) != 0 &&
   112              (dir->name = (char *)DIRENT_MALLOC(base_length + strlen(all) + 1)) != 0)
   113          {
   114              strcat(strcpy(dir->name, name), all);
   115  
   116              if ((dir->handle = (handle_type) _findfirst(dir->name, &dir->info)) != -1)
   117              {
   118                  dir->result.d_name = 0;
   119              }
   120              else  // rollback
   121              {
   122                  DIRENT_FREE(dir->name);
   123                  DIRENT_FREE(dir);
   124                  dir = 0;
   125              }
   126          }
   127          else  // rollback
   128          {
   129              DIRENT_FREE(dir);
   130              dir   = 0;
   131              errno = ENOMEM;
   132          }
   133      }
   134      else errno = EINVAL;
   135  
   136      return dir;
   137  }
   138  
   139  int closedir(DIR *dir)
   140  {
   141      int result = -1;
   142  
   143      if (dir)
   144      {
   145          if (dir->handle != -1) result = _findclose(dir->handle);
   146  
   147          DIRENT_FREE(dir->name);
   148          DIRENT_FREE(dir);
   149      }
   150  
   151      // NOTE: All errors ampped to EBADF
   152      if (result == -1) errno = EBADF;
   153  
   154      return result;
   155  }
   156  
   157  struct dirent *readdir(DIR *dir)
   158  {
   159      struct dirent *result = 0;
   160  
   161      if (dir && dir->handle != -1)
   162      {
   163          if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
   164          {
   165              result = &dir->result;
   166              result->d_name = dir->info.name;
   167          }
   168      }
   169      else errno = EBADF;
   170  
   171      return result;
   172  }
   173  
   174  void rewinddir(DIR *dir)
   175  {
   176      if (dir && dir->handle != -1)
   177      {
   178          _findclose(dir->handle);
   179          dir->handle = (handle_type) _findfirst(dir->name, &dir->info);
   180          dir->result.d_name = 0;
   181      }
   182      else errno = EBADF;
   183  }