stagit-fork

a stagit fork compatible with Windows (original: https://codemadness.org/git/stagit)
git clone https://github.com/5hif7y/stagit.git
Log | Files | Refs | README | LICENSE

wincompat.h (4175B)


      1 /* C99 (ISO/IEC 9899:1999) - 5hif7y */
      2 /* A little helper to force POSIX compatibility for suckless tools on Windows */
      3 
      4 #ifndef WINCOMPAT_H
      5 #define WINCOMPAT_H
      6 #ifdef _WIN32
      7 
      8 #pragma warning(disable:4996) /* TODO: reimplement '_fdopen' for MSVC */
      9 //#define _CRT_SECURE_NO_WARNINGS /* TODO: use secure implementation 'strcpy' to 'strcpy_s' */
     10 #define WIN32_LEAN_AND_MEAN
     11 #include <windows.h>
     12 #include <sys/stat.h>
     13 #include <io.h>
     14 #include <direct.h>
     15 #include <fcntl.h>
     16 #include <stdlib.h>
     17 
     18 /* --------- posix datatype --------- */
     19 typedef int mode_t;
     20 
     21 /* --------- misc defines --------- */
     22 #define PATH_MAX 260
     23 #ifdef _MSC_VER
     24   #define access _access
     25   #define fdopen _fdopen /* TODO: reimplement 'fdopen' for Windows MSVC */
     26   #define umask _umask
     27   #define chmod _chmod
     28 #endif
     29 #define warnx(fmt, ...) (fprintf(stderr, fmt "\n", ##__VA_ARGS__))
     30 #define err(exitcode, fmt, ...) do { \
     31     fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
     32     exit(exitcode); \
     33 } while (0)
     34 #define errx(exitcode, fmt, ...) err(exitcode, fmt, ##__VA_ARGS__)
     35 /* if your toolchain is using MSVC, use the native implementation '_strdup' */
     36 #if defined(_MSC_VER)
     37   #define strdup _strdup
     38 /* Use this if your toolchain doesn't have an 'strdup' implementation */
     39 #elif defined(CUSTOM_STRDUP)
     40   static char *custom_strdup(const char *s){
     41     if(!s){ return NULL;}
     42     size_t len = strlen(s) + 1;
     43     char *copy = malloc(len);
     44     if (copy) { memcpy(copy, s, len); }
     45     return copy;
     46   }
     47   #define strdup custom_strdup
     48 #endif /* _MSC_VER xor CUSTOM_STRDUP */
     49 
     50 /* --------- posix functions reimplementations --------- */
     51 static int mkstemp(char *templte){
     52   char *XXXXXX = strstr(templte, "XXXXXX");
     53   if (!XXXXXX || strlen(XXXXXX) != 6) {
     54     return -1;
     55   }
     56   for (int i = 0; i < 100; ++i) {
     57     for (int j = 0; j < 6; ++j) {
     58       XXXXXX[j] = 'A' + rand() % 26;
     59     }
     60     int fd = _open(templte, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
     61     if (fd != -1) {
     62       return fd;
     63     }
     64   }
     65   return -1;
     66 }
     67 
     68 static char *win_basename(const char *path){
     69   if (!path || !*path){ return NULL; }
     70  
     71   const char *last_slash = strrchr(path, '\\');
     72   const char *last_fslash = strrchr(path, '/');
     73   const char *base = path;
     74   
     75   if (last_slash && last_fslash){
     76     base = (last_slash > last_fslash) ? last_slash + 1 : last_fslash + 1;
     77   }
     78   else if (last_slash) {
     79     base = last_slash + 1;
     80   }
     81   else if (last_fslash){
     82     base = last_fslash + 1;
     83   }
     84   return strdup(base);
     85 }
     86 #define basename(path) win_basename(path)
     87 
     88 static char *win_dirname(char *path){
     89   static char buffer[MAX_PATH];
     90   char *slash;
     91   if (!path || !*path){ 
     92     strcpy(buffer, "."); 
     93     return buffer;
     94   }
     95   strncpy(buffer, path, MAX_PATH);
     96   buffer[MAX_PATH - 1] = '\0';  // prevenir falta de terminación nula
     97   slash = strrchr(buffer, '\\');
     98   if (!slash){
     99     slash = strrchr(buffer, '/');
    100   }
    101   if (slash){
    102     *slash = '\0';
    103   } else {
    104     strcpy(buffer, ".");
    105   }
    106   return buffer;
    107 }
    108 #define dirname(path) win_dirname(path)
    109 
    110 static char *realpath(const char *path, char *resolved_path){
    111   if(!resolved_path){ resolved_path = (char*)malloc(MAX_PATH); }
    112   _fullpath(resolved_path, path, MAX_PATH);
    113   return resolved_path;
    114 }
    115 
    116 static int win_mkdir(const char *path, mode_t mode){
    117   (void)mode; /* discard unused variable in a way the compiler doesn't complain */
    118   return _mkdir(path);
    119 }
    120 #define mkdir(path, mode) win_mkdir(path, mode)
    121 
    122 /* --------- access --------- */
    123 #ifndef F_OK
    124 #define F_OK 0
    125 #endif
    126 
    127 /* --------- permission macros --------- */
    128 #define S_IRWXU 0700
    129 #define S_IRUSR 0400
    130 #define S_IWUSR 0200
    131 #define S_IXUSR 0100
    132 #define S_IRWXG 0070
    133 #define S_IRGRP 0040
    134 #define S_IWGRP 0020
    135 #define S_IXGRP 0010
    136 #define S_IRWXO 0007
    137 #define S_IROTH 0004
    138 #define S_IWOTH 0002
    139 #define S_IXOTH 0001
    140 #define S_ISUID 0004000
    141 #define S_ISGID 0002000
    142 #define S_ISVTX 0001000
    143 
    144 /* --------- S_ISXXX macros --------- */
    145 #define S_ISREG(m)  (((m) & S_IFMT) == S_IFREG)
    146 #define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
    147 #define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)
    148 #define S_ISBLK(m)  (0)  // doesn't exist in Windows
    149 #define S_ISFIFO(m) (0)
    150 #define S_ISLNK(m)  (0)
    151 #define S_ISSOCK(m) (0)
    152 
    153 #endif /* _WIN32 */
    154 #endif /* WINCOMPAT_H */