misc.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. misc.h - miscellaneous functions
  3. Copyright (c) 1999 - 2004 NoisyB
  4. Copyright (c) 2001 - 2004, 2015 dbjh
  5. Copyright (c) 2002 - 2004 Jan-Erik Karlsson (Amiga code)
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #ifndef MISC_H
  19. #define MISC_H
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h" // USE_ZLIB, USE_ANSI_COLOR support
  22. #endif
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. #include <string.h>
  27. #ifdef _MSC_VER
  28. #pragma warning(push)
  29. #pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
  30. #endif
  31. #include <time.h> // gauge() prototype contains time_t
  32. #ifdef _MSC_VER
  33. #pragma warning(pop)
  34. #endif
  35. #include <stdio.h>
  36. #ifdef USE_ZLIB
  37. #include "misc_z.h"
  38. #endif // USE_ZLIB
  39. #ifdef __sun
  40. #ifdef __SVR4
  41. #define __solaris__
  42. #endif
  43. #endif
  44. #ifdef HAVE_INTTYPES_H
  45. #include <inttypes.h>
  46. #else // __MSDOS__, _WIN32 (VC++)
  47. #ifndef OWN_INTTYPES
  48. #define OWN_INTTYPES // signal that these are defined
  49. typedef unsigned char uint8_t;
  50. typedef signed char int8_t;
  51. typedef unsigned short int uint16_t;
  52. typedef signed short int int16_t;
  53. typedef unsigned int uint32_t;
  54. typedef signed int int32_t;
  55. #ifndef _WIN32
  56. typedef unsigned long long int uint64_t;
  57. typedef signed long long int int64_t;
  58. #else
  59. typedef unsigned __int64 uint64_t;
  60. typedef signed __int64 int64_t;
  61. #endif
  62. #endif // OWN_INTTYPES
  63. #endif
  64. #if (defined __unix__ && !defined __MSDOS__) || defined __BEOS__ || \
  65. defined AMIGA || defined __APPLE__ // Mac OS X actually
  66. // GNU/Linux, Solaris, FreeBSD, Cygwin, BeOS, Amiga, Mac (OS X)
  67. #define DIR_SEPARATOR '/'
  68. #define DIR_SEPARATOR_S "/"
  69. #else // DJGPP, Win32
  70. #define DIR_SEPARATOR '\\'
  71. #define DIR_SEPARATOR_S "\\"
  72. #endif
  73. #ifndef MAXBUFSIZE
  74. #define MAXBUFSIZE 32768
  75. #endif // MAXBUFSIZE
  76. #ifndef ARGS_MAX
  77. #define ARGS_MAX 128
  78. #endif // ARGS_MAX
  79. #if (!defined TRUE || !defined FALSE)
  80. #define FALSE 0
  81. #define TRUE (!FALSE)
  82. #endif
  83. #ifndef MIN
  84. #define MIN(a,b) ((a)<(b)?(a):(b))
  85. #endif
  86. #ifndef MAX
  87. #define MAX(a,b) ((a)>(b)?(a):(b))
  88. #endif
  89. #define LIB_VERSION(ver, rel, seq) (((ver) << 16) | ((rel) << 8) | (seq))
  90. #define NULL_TO_EMPTY(str) ((str) ? (str) : (""))
  91. //#define RANDOM(min, max) ((rand () % (max - min)) + min)
  92. #define OFFSET(a, offset) ((((unsigned char *)&(a))+(offset))[0])
  93. #ifdef WORDS_BIGENDIAN
  94. #undef WORDS_BIGENDIAN
  95. #endif
  96. #if defined _LIBC || defined __GLIBC__
  97. #include <endian.h>
  98. #if __BYTE_ORDER == __BIG_ENDIAN
  99. #define WORDS_BIGENDIAN 1
  100. #endif
  101. #elif defined AMIGA || defined __sparc__ || defined __BIG_ENDIAN__ || \
  102. defined __APPLE__
  103. #define WORDS_BIGENDIAN 1
  104. #endif
  105. #ifdef __MSDOS__ // __MSDOS__ must come before __unix__,
  106. #define CURRENT_OS_S "MS-DOS" // because DJGPP defines both
  107. #elif defined __unix__
  108. #ifdef __CYGWIN__
  109. #define CURRENT_OS_S "Win32 (Cygwin)"
  110. #elif defined __FreeBSD__
  111. #define CURRENT_OS_S "UNIX (FreeBSD)"
  112. #elif defined __OpenBSD__
  113. #define CURRENT_OS_S "UNIX (OpenBSD)"
  114. #elif defined __linux__
  115. #define CURRENT_OS_S "UNIX (Linux)"
  116. #elif defined __solaris__
  117. #ifdef __sparc__
  118. #define CURRENT_OS_S "UNIX (Solaris/Sparc)"
  119. #else
  120. #define CURRENT_OS_S "UNIX (Solaris/i386)"
  121. #endif
  122. #else
  123. #define CURRENT_OS_S "UNIX"
  124. #endif
  125. #elif defined _WIN32
  126. #ifdef __MINGW32__
  127. #define CURRENT_OS_S "Win32 (MinGW)"
  128. #else
  129. #define CURRENT_OS_S "Win32 (Visual C++)"
  130. #endif
  131. #elif defined __APPLE__
  132. #if defined __POWERPC__ || defined __ppc__
  133. #define CURRENT_OS_S "Apple (PPC)"
  134. #else
  135. #define CURRENT_OS_S "Apple"
  136. #endif
  137. #elif defined __BEOS__
  138. #define CURRENT_OS_S "BeOS"
  139. #elif defined AMIGA
  140. #if defined __PPC__
  141. #define CURRENT_OS_S "Amiga (PPC)"
  142. #else
  143. #define CURRENT_OS_S "Amiga (68K)"
  144. #endif
  145. #else
  146. #define CURRENT_OS_S "?"
  147. #endif
  148. /*
  149. mem functions
  150. memwcmp() memcmp with wildcard support
  151. mem_search() search for a byte sequence
  152. mem_swap_b() swap n bytes of buffer
  153. mem_swap_w() swap n/2 words of buffer
  154. mem_hexdump() hexdump n bytes of buffer; you can use here a virtual_start for the displayed counter
  155. */
  156. #ifdef HAVE_BYTESWAP_H
  157. #include <byteswap.h>
  158. #else
  159. extern uint16_t bswap_16 (uint16_t x);
  160. extern uint32_t bswap_32 (uint32_t x);
  161. extern uint64_t bswap_64 (uint64_t x);
  162. #endif
  163. #ifdef WORDS_BIGENDIAN
  164. #define me2be_16(x) (x)
  165. #define me2be_32(x) (x)
  166. #define me2be_64(x) (x)
  167. #define me2le_16(x) (bswap_16(x))
  168. #define me2le_32(x) (bswap_32(x))
  169. #define me2le_64(x) (bswap_64(x))
  170. #define be2me_16(x) (x)
  171. #define be2me_32(x) (x)
  172. #define be2me_64(x) (x)
  173. #define le2me_16(x) (bswap_16(x))
  174. #define le2me_32(x) (bswap_32(x))
  175. #define le2me_64(x) (bswap_64(x))
  176. #else
  177. #define me2be_16(x) (bswap_16(x))
  178. #define me2be_32(x) (bswap_32(x))
  179. #define me2be_64(x) (bswap_64(x))
  180. #define me2le_16(x) (x)
  181. #define me2le_32(x) (x)
  182. #define me2le_64(x) (x)
  183. #define be2me_16(x) (bswap_16(x))
  184. #define be2me_32(x) (bswap_32(x))
  185. #define be2me_64(x) (bswap_64(x))
  186. #define le2me_16(x) (x)
  187. #define le2me_32(x) (x)
  188. #define le2me_64(x) (x)
  189. #endif
  190. extern int memwcmp (const void *buffer, const void *search, uint32_t searchlen, int wildcard);
  191. extern void *mem_search (const void *buffer, uint32_t buflen, const void *search, uint32_t searchlen);
  192. extern void *mem_swap_b (void *buffer, uint32_t n);
  193. extern void *mem_swap_w (void *buffer, uint32_t n);
  194. extern void mem_hexdump (const void *buffer, uint32_t n, int virtual_start);
  195. /*
  196. String manipulation
  197. isfname() test if char could be used for filenames
  198. isprint2() test if char could be used for stdout
  199. tofname() replaces chars that can not be used for filenames
  200. toprint2() replaces chars that should not be used for stdout
  201. is_func() use all is*() functions on an array of char
  202. to_func() use all to*() functions on an array of char
  203. strtrim() trim isspace()'s from start and end of string
  204. strncpy2() a safer strncpy that DOES terminate a string
  205. is_upper2() wrapper for is_upper() (DAMN stupid programmers!)
  206. set_suffix() set/replace suffix of filename with suffix
  207. suffix means in this case the suffix INCLUDING the dot '.'
  208. set_suffix_i() like set_suffix(), but doesn't change the case
  209. get_suffix() get suffix of filename
  210. basename2() DJGPP basename() clone
  211. dirname2() DJGPP dirname() clone
  212. realpath2() realpath() replacement
  213. one_file() returns 1 if two filenames refer to one file, otherwise it
  214. returns 0
  215. one_filesystem() returns 1 if two filenames refer to files on one file
  216. system, otherwise it returns 0
  217. mkdir2() mkdir() wrapper who automatically cares for rights, etc.
  218. rename2() renames oldname to newname even if oldname and newname are not
  219. on one file system
  220. truncate2() don't use truncate() to enlarge files, because the result is
  221. undefined (by POSIX) use truncate2() instead which does both
  222. strarg() break a string into tokens
  223. */
  224. extern int isfname (int c);
  225. extern int isprint2 (int c);
  226. extern int tofname (int c);
  227. extern int toprint2 (int c);
  228. extern int is_func (char *s, int size, int (*func) (int));
  229. extern char *to_func (char *s, int size, int (*func) (int));
  230. #define strupr(s) (to_func(s, strlen(s), toupper))
  231. #define strlwr(s) (to_func(s, strlen(s), tolower))
  232. //#ifndef HAVE_STRCASESTR
  233. // strcasestr is GNU only
  234. extern char *strcasestr2 (const char *str, const char *search);
  235. #define stristr strcasestr2
  236. //#else
  237. //#define stristr strcasestr
  238. //#endif
  239. #ifndef _WIN32
  240. #define stricmp strcasecmp
  241. #define strnicmp strncasecmp
  242. #endif
  243. extern char *strtrim (char *str);
  244. extern char *strncpy2 (char *dest, const char *src, size_t size);
  245. extern int isupper2 (int c);
  246. extern char *set_suffix (char *filename, const char *suffix);
  247. extern char *set_suffix_i (char *filename, const char *suffix);
  248. extern const char *get_suffix (const char *filename);
  249. extern char *basename2 (const char *path);
  250. // override a possible XPG basename() which modifies its arg
  251. #define basename basename2
  252. extern char *dirname2 (const char *path);
  253. #define dirname dirname2
  254. extern int one_file (const char *filename1, const char *filename2);
  255. extern int one_filesystem (const char *filename1, const char *filename2);
  256. extern char *realpath2 (const char *src, char *full_path);
  257. extern int mkdir2 (const char *name);
  258. extern int rename2 (const char *oldname, const char *newname);
  259. extern int truncate2 (const char *filename, int size);
  260. extern int strarg (char **argv, char *str, const char *separator_s, int max_args);
  261. /*
  262. Misc stuff
  263. change_mem{2}() see header of implementation for usage
  264. build_cm_patterns() helper function for change_mem2() to read search patterns
  265. from a file
  266. cleanup_cm_patterns() helper function for build_cm_patterns() to free all
  267. memory allocated for a (list of) st_pattern_t structure(s)
  268. clear_line () clear the current line (79 spaces)
  269. ansi_init() initialize ANSI output
  270. ansi_strip() strip ANSI codes from a string
  271. gauge() init_time == time when gauge() was first started or when
  272. the transfer started
  273. pos == current position
  274. size == full size
  275. gauge given these three values will calculate many
  276. informative things like time, status bar, cps, etc.
  277. it can be used for procedures which take some time to
  278. inform the user about the actual progress
  279. getenv2() getenv() clone for enviroments w/o HOME, TMP or TEMP variables
  280. tmpnam2() replacement for tmpnam() temp must have the size of FILENAME_MAX
  281. renlwr() renames all files tolower()
  282. drop_privileges() switch to the real user and group id (leave "root mode")
  283. register_func() atexit() replacement
  284. returns -1 if it fails, 0 if it was successful
  285. unregister_func() unregisters a previously registered function
  286. returns -1 if it fails, 0 if it was successful
  287. handle_registered_funcs() calls all the registered functions
  288. wait2 wait (sleep) a specified number of milliseconds
  289. */
  290. typedef struct st_cm_set
  291. {
  292. char *data;
  293. int size;
  294. } st_cm_set_t;
  295. typedef struct st_cm_pattern
  296. {
  297. #ifdef _MSC_VER
  298. #pragma warning(push)
  299. #pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
  300. #endif
  301. char *search, wildcard, escape, *replace;
  302. #ifdef _MSC_VER
  303. #pragma warning(pop)
  304. #endif
  305. int search_size, replace_size, offset, n_sets;
  306. st_cm_set_t *sets;
  307. } st_cm_pattern_t;
  308. extern int change_mem (char *buf, int bufsize, char *searchstr, int strsize,
  309. char wc, char esc, char *newstr, int newsize, int offset, ...);
  310. extern int change_mem2 (char *buf, int bufsize, char *searchstr, int strsize,
  311. char wc, char esc, char *newstr, int newsize,
  312. int offset, st_cm_set_t *sets);
  313. extern int build_cm_patterns (st_cm_pattern_t **patterns, const char *filename, int verbose);
  314. extern void cleanup_cm_patterns (st_cm_pattern_t **patterns, int n_patterns);
  315. extern void clear_line (void);
  316. extern int ansi_init (void);
  317. extern char *ansi_strip (char *str);
  318. extern int gauge (time_t init_time, int pos, int size);
  319. extern char *getenv2 (const char *variable);
  320. extern char *tmpnam2 (char *temp);
  321. //extern int renlwr (const char *path);
  322. #if defined __unix__ && !defined __MSDOS__
  323. extern int drop_privileges (void);
  324. #endif
  325. extern int register_func (void (*func) (void));
  326. extern int unregister_func (void (*func) (void));
  327. extern void handle_registered_funcs (void);
  328. extern void wait2 (int nmillis);
  329. /*
  330. Extended getopt(), usage and workflow handling
  331. getopt2_usage() a renderer for a nice usage output
  332. takes an st_getopt2_t array
  333. getop2_parse_usage() parse usage output into st_getopt2_t
  334. array (for development)
  335. getopt2_long() turn st_getopt2_t into struct option for getopt1()
  336. getopt2_short() turn st_getopt2_t shortoptions string for getopt1()
  337. getopt2_get_index_by_val()
  338. */
  339. #include "getopt.h" // getopt2 needs struct option from getopt1
  340. #define OPTION '-'
  341. #define OPTION_S "-"
  342. #define OPTION_LONG_S "--"
  343. #define OPTARG '='
  344. #define OPTARG_S "="
  345. typedef struct
  346. {
  347. const char *name; // see getopt()
  348. int has_arg; // see getopt()
  349. int *flag; // see getopt()
  350. int val; // see getopt()
  351. const char *arg_name; // name of the options arg as it should be
  352. // displayed in the --help output
  353. // "--name=arg_name" if has_arg == 1
  354. // "--name[=arg_name]" if has_arg == 2
  355. const char *help; // --help, -h, -? output for the current option
  356. void *object; // could be used for workflow objects
  357. } st_getopt2_t;
  358. extern void getopt2_usage (const st_getopt2_t *option);
  359. #ifdef DEBUG
  360. extern void getopt2_parse_usage (const char *usage_output);
  361. #endif
  362. extern int getopt2_long (struct option *long_option, const st_getopt2_t *option, int n);
  363. extern int getopt2_short (char *short_option, const st_getopt2_t *option, int n);
  364. extern const st_getopt2_t *getopt2_get_index_by_val (const st_getopt2_t *option, int val);
  365. /*
  366. Quick I/O
  367. mode
  368. "r", "rb", "w", "wb", "a", "ab"
  369. quick_io_c() returns byte read or fputc()'s status
  370. quick_io() returns number of bytes read or written
  371. Macros
  372. q_fread() same as fread but takes start and src is a filename
  373. q_fwrite() same as fwrite but takes start and dest is a filename; mode
  374. is the same as fopen() modes
  375. q_fgetc() same as fgetc but takes filename instead of FILE and a pos
  376. q_fputc() same as fputc but takes filename instead of FILE and a pos
  377. b,s,l,f,m == buffer,start,len,filename,mode
  378. Misc
  379. q_fncmp() search in filename from start len bytes for the first appearance
  380. of search which has searchlen
  381. wildcard could be one character or -1 (wildcard off)
  382. q_fcpy() copy src from start for len to dest with mode (fopen(..., mode))
  383. q_rfcpy() copy src to dest without looking at the file data (no
  384. decompression like with q_fcpy())
  385. q_fswap() swap len bytes of file starting from start
  386. q_fbackup()
  387. modes
  388. BAK_DUPE (default)
  389. rename file to keep attributes and copy it back to old name and return
  390. new name
  391. filename -> rename() -> buf -> f_cpy() -> filename -> return buf
  392. BAK_MOVE
  393. just rename file and return new name (static)
  394. filename -> rename() -> buf -> return buf
  395. */
  396. extern int quick_io (void *buffer, size_t start, size_t len, const char *fname, const char *mode);
  397. extern int quick_io_c (int value, size_t start, const char *fname, const char *mode);
  398. #define q_fread(b,s,l,f) (quick_io(b,s,l,f,"rb"))
  399. #define q_fwrite(b,s,l,f,m) (quick_io((void *)b,s,l,f,m))
  400. #define q_fgetc(f,s) (quick_io_c(0,s,f,"rb"))
  401. #define q_fputc(f,s,b,m) (quick_io_c(b,s,f,m))
  402. typedef enum { SWAP_BYTE, SWAP_WORD } swap_t;
  403. extern int q_fncmp (const char *filename, int start, int len,
  404. const char *search, int searchlen, int wildcard);
  405. extern int q_fcpy (const char *src, int start, int len, const char *dest, const char *mode);
  406. extern int q_rfcpy (const char *src, const char *dest);
  407. extern int q_fswap (const char *filename, int start, int len, swap_t type);
  408. #define q_fswap_b(f, s, l) q_fswap(f, s, l, SWAP_BYTE)
  409. #define q_fswap_w(f, s, l) q_fswap(f, s, l, SWAP_WORD)
  410. #if 1
  411. #define BAK_DUPE 0
  412. #define BAK_MOVE 1
  413. extern char *q_fbackup (const char *filename, int mode);
  414. #else
  415. extern char *q_fbackup (char *move_name, const char *filename);
  416. #endif
  417. #ifndef USE_ZLIB
  418. extern int q_fsize (const char *filename);
  419. #endif
  420. /*
  421. Configuration file handling
  422. get_property() get value of propname from filename or return value of env
  423. with name like propname or return def
  424. get_property_int() like get_property() but returns an integer which is 0
  425. if the value of propname was 0, [Nn] or [Nn][Oo] and an
  426. integer or at least 1 for every other case
  427. get_property_fname() like get_property() but specifically for filenames,
  428. i.e., it runs realpath2() on the filename and fixes the
  429. characters if necessary (Cygwin)
  430. set_property() set propname with value in filename
  431. DELETE_PROPERTY() like set_property but when value of propname is NULL the
  432. whole property will disappear from filename
  433. */
  434. #define PROPERTY_SEPARATOR '='
  435. #define PROPERTY_SEPARATOR_S "="
  436. #define PROPERTY_COMMENT '#'
  437. #define PROPERTY_COMMENT_S "#"
  438. extern char *get_property (const char *filename, const char *propname,
  439. char *value, const char *def);
  440. extern int32_t get_property_int (const char *filename, const char *propname);
  441. extern char *get_property_fname (const char *filename, const char *propname,
  442. char *buffer, const char *def);
  443. extern int set_property (const char *filename, const char *propname,
  444. const char *value, const char *comment);
  445. #define DELETE_PROPERTY(a, b) (set_property(a, b, NULL, NULL))
  446. /*
  447. Portability (conio.h, etc...)
  448. init_conio() init console I/O
  449. deinit_conio() stop console I/O
  450. getch()
  451. kbhit()
  452. truncate()
  453. sync()
  454. popen()
  455. pclose()
  456. vprintf2()
  457. printf2()
  458. fprintf2()
  459. */
  460. #if (defined __unix__ && !defined __MSDOS__) || defined __BEOS__ || \
  461. defined __APPLE__ // Mac OS X actually
  462. extern void init_conio (void);
  463. extern void deinit_conio (void);
  464. #define getch getchar // getchar() acts like DOS getch() after init_conio()
  465. extern int kbhit (void); // may only be used after init_conio()!
  466. #elif defined __MSDOS__
  467. #include <conio.h> // getch()
  468. #include <pc.h> // kbhit()
  469. #elif defined _WIN32
  470. #include <conio.h> // kbhit() & getch()
  471. #elif defined AMIGA
  472. extern int kbhit (void);
  473. //#define getch getchar
  474. // Gonna use my (Jan-Erik) fake one. Might work better and more like the real
  475. // getch().
  476. #endif
  477. #ifdef _WIN32
  478. // Note that _WIN32 is defined by cl.exe while the other constants (like WIN32)
  479. // are defined in header files. MinGW's gcc.exe defines all constants.
  480. #include <sys/types.h>
  481. extern int truncate (const char *path, off_t size);
  482. extern int sync (void);
  483. // For MinGW popen() and pclose() are unavailable for DLL's. For DLL's _popen()
  484. // and _pclose() should be used. Visual C++ only has the latter two.
  485. #ifndef pclose // misc_z.h's definition gets higher precedence
  486. #define pclose _pclose
  487. #endif
  488. #ifndef popen // idem
  489. #define popen _popen
  490. #endif
  491. #ifdef USE_ANSI_COLOR
  492. #include <stdarg.h>
  493. extern int vprintf2 (const char *format, va_list argptr);
  494. extern int printf2 (const char *format, ...);
  495. extern int fprintf2 (FILE *file, const char *format, ...);
  496. #define vprintf vprintf2
  497. #define printf printf2
  498. #define fprintf fprintf2
  499. #endif // USE_ANSI_COLOR
  500. #ifndef __MINGW32__
  501. #ifdef _MSC_VER
  502. #pragma warning(push)
  503. #pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
  504. #endif
  505. #include <io.h>
  506. #include <sys/stat.h> // According to MSDN <sys/stat.h> must
  507. #ifdef _MSC_VER // come after <sys/types.h>. Yep, that's M$.
  508. #pragma warning(pop)
  509. #endif
  510. #include <direct.h>
  511. #define S_IWUSR _S_IWRITE
  512. #define S_IRUSR _S_IREAD
  513. #define S_ISDIR(mode) ((mode) & _S_IFDIR ? 1 : 0)
  514. #define S_ISREG(mode) ((mode) & _S_IFREG ? 1 : 0)
  515. #define F_OK 00
  516. #define W_OK 02
  517. #define R_OK 04
  518. #define X_OK R_OK // this is correct for dirs, but not for exes
  519. #define STDIN_FILENO (fileno (stdin))
  520. #define STDOUT_FILENO (fileno (stdout))
  521. #define STDERR_FILENO (fileno (stderr))
  522. #else
  523. #ifdef DLL
  524. #define access _access
  525. #define chmod _chmod
  526. //#define fileno _fileno
  527. #define getcwd _getcwd
  528. #define isatty _isatty
  529. #define rmdir _rmdir
  530. #define stat _stat
  531. #define strdup _strdup
  532. #define stricmp _stricmp
  533. #define strnicmp _strnicmp
  534. #endif // DLL
  535. #endif // !__MINGW32__
  536. #elif defined AMIGA // _WIN32
  537. // custom _popen() and _pclose(), because the standard ones (named popen() and
  538. // pclose()) are buggy
  539. #ifndef pclose // misc_z.h's definition gets higher precedence
  540. #define pclose _pclose
  541. #endif
  542. #ifndef popen // idem
  543. #define popen _popen
  544. #endif
  545. extern FILE *_popen (const char *path, const char *mode);
  546. extern int _pclose (FILE *stream);
  547. #endif // AMIGA
  548. #ifdef __cplusplus
  549. }
  550. #endif
  551. #endif // MISC_H