minesweeper

A minewseeper implementation to play around with Hare and Raylib
git clone https://git.tronto.net/minesweeper
Download | Log | Files | Refs | README | LICENSE

dirent.h (5184B)


      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 }