/*	
 *	clipstdw_x64.h
 *
 *	Win32プロジェクト用の追加標準関数宣言
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2015-2017 Naoyuki Sawa
 *
 *	* Sat Sep 03 14:13:50 JST 2016 Naoyuki Sawa
 *	- 作成開始。
 *	- clipstdw.hの、64ビット用の代替バージョンです。
 *	  将来的にはclipstdw.hにマージしたいですが、当面は混乱を防ぐためにファイルを分ける事にしました。
 *	- 64ビット特有の箇所以外は、基本的には32ビット版と同じなので、詳細なコメントは記載していません。
 *	  詳細なコメントについては、元バージョンを参照して下さい。
 */
#ifndef __CLIP_STDW_X64_H__
#define __CLIP_STDW_X64_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
/****************************************************************************
 *	include/sys/stat.h
 ****************************************************************************/
#define S_ISREG(m)	(((m)&S_IFMT)==S_IFREG)	/* is it a regular file? */
#define S_ISDIR(m)	(((m)&S_IFMT)==S_IFDIR)	/* is it a directory? */
#define S_ISCHR(m)	(((m)&S_IFMT)==S_IFCHR)	/* is it a character device? */
#define S_ISFIFO(m)	(((m)&S_IFMT)==S_IFIFO)	/* is it a FIFO? */
/****************************************************************************
 *	include/sys/types.h
 ****************************************************************************/
typedef SSIZE_T		ssize_t;	/* size of something in bytes or -1 */
/****************************************************************************
 *	include/assert.h
 ****************************************************************************/
#if     (_MSC_VER < 1900)	//{{VC++2015ではCソースでもC++ソースでも組み込みstatic_assertが使えるので、ここで定義する必要は有りません。VC++2015の組み込みstatic_assertはマクロではないので、'#ifndef static_assert'では判定出来ない事に注意して下さい。
#ifndef static_assert
#define _Static_assert(expression,message) typedef char __Static_assert__[(expression)?1:-1]	//厳密には'_Static_assert'はC11のキーワードであってマクロではないのですが、当ライブラリではマクロとして実装する事にしました。マクロでの実装方法については、「Windows Dev Center - C_ASSERT macro」(https://msdn.microsoft.com/en-us/library/windows/desktop/ms679289(v=vs.85).aspx)を参考にしました。同じtypedef名(この場合は__Static_assert__)を複数回使用しても、同じ定義内容ならばエラーにならない事を利用しています。
#define static_assert _Static_assert
#endif//static_assert
#endif//(_MSC_VER < 1900)	//}}VC++2015ではCソースでもC++ソースでも組み込みstatic_assertが使えるので、ここで定義する必要は有りません。VC++2015の組み込みstatic_assertはマクロではないので、'#ifndef static_assert'では判定出来ない事に注意して下さい。
/****************************************************************************
 *	include/ctype.h
 ****************************************************************************/
//'C:/program files (x86)/windows kits/10/include/10.0.10240.0/ucrt/ctype.h'のマクロ定義を取り消す。
#undef  isdigit
#undef  isxdigit
#undef  isupper
#undef  islower
#undef  isalpha
#undef  isalnum
#undef  iscsymf
#undef  iscsym
#undef  iscntrl
#undef  isblank
#undef  isspace
#undef  isgraph
#undef  isprint
#undef  ispunct
#undef  ismbblead
#undef  ismbbtrail
#undef  toupper
#undef  tolower
//⇒ctype.c
#define isdigit		internal_isdigit
#define isxdigit	internal_isxdigit
#define isupper		internal_isupper
#define islower		internal_islower
#define isalpha		internal_isalpha
#define isalnum		internal_isalnum
#define iscsymf		internal_iscsymf
#define iscsym		internal_iscsym
#define iscntrl		internal_iscntrl
#define isblank		internal_isblank
#define isspace		internal_isspace
#define isgraph		internal_isgraph
#define isprint		internal_isprint
#define ispunct		internal_ispunct
#define ismbblead	internal_ismbblead
#define ismbbtrail	internal_ismbbtrail
#define toupper		internal_toupper
#define tolower		internal_tolower
int isdigit(int c);
int isxdigit(int c);
int isupper(int c);
int islower(int c);
int isalpha(int c);
int isalnum(int c);
int iscsymf(int c);
int iscsym(int c);
int iscntrl(int c);
int isblank(int c);
int isspace(int c);
int isgraph(int c);
int isprint(int c);
int ispunct(int c);
int ismbblead(int c);
int ismbbtrail(int c);
int toupper(int c);
int tolower(int c);
/****************************************************************************
 *	include/errno.h
 ****************************************************************************/
//{{2016/09/08削除:Windows環境ならばprogram_invocation_name,program_invocation_short_nameをcliplibc.hで宣言するようにしたので、cliplibc.hでの宣言は不要になりました。
////⇒cliplibc.c
//extern char* program_invocation_name;
//extern char* program_invocation_short_name;
//}}2016/09/08削除:Windows環境ならばprogram_invocation_name,program_invocation_short_nameをcliplibc.hで宣言するようにしたので、cliplibc.hでの宣言は不要になりました。
/****************************************************************************
 *	include/stdio.h
 ****************************************************************************/
//⇒clipprnt.c
int snprintf(char* out, size_t cnt, const char* fmt, ...);		//Visual C++の_snprintf() ではなく、clipprnt.cのsnprintf() を使用する事にしました。
int vsnprintf(char* out, size_t cnt, const char* fmt, va_list ap);	//Visual C++の_vsnprintf()ではなく、clipprnt.cのvsnprintf()を使用する事にしました。
int scprintf(const char* fmt, ...);
int vscprintf(const char* fmt, va_list ap);
int asprintf(char** strp, const char* fmt, ...);
int vasprintf(char** strp, const char* fmt, va_list ap);
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define vsprintf	internal_vsprintf
#define sprintf		internal_sprintf
#define vsnprintf	internal_vsnprintf
#define snprintf	internal_snprintf
#define fprintf		internal_fprintf
#define printf		internal_printf
#define vfprintf	internal_vfprintf
#define vprintf		internal_vprintf
int vsprintf(char* out, const char* fmt, va_list ap);
int sprintf(char* out, const char* fmt, ...);
int vsnprintf(char* out, size_t cnt, const char* fmt, va_list ap);
int snprintf(char* out, size_t cnt, const char* fmt, ...);
int fprintf(FILE* stream, const char* format, ...);
int printf(const char* format, ...);
int vfprintf(FILE* stream, const char* format, va_list argptr);
int vprintf(const char* format, va_list argptr);
/*--------------------------------------------------------------------------*/
//⇒clipscan.c
int vscanf(const char* fmt, va_list ap);
int vsscanf(const char* str, const char* fmt, va_list ap);
int vfscanf(FILE* stream, const char* fmt, va_list ap);
/*--------------------------------------------------------------------------*/
//⇒getline.c
ssize_t getline(char** lineptr, size_t* n, FILE* stream);
ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* stream);
/****************************************************************************
 *	include/stdlib.h
 ****************************************************************************/
//#define MAX_PATH	_MAX_PATH	//_MAX_PATH ⇒STDLIB.H,MAX_PATH⇒WINDEF.H
#define MAX_DRIVE	_MAX_DRIVE	//_MAX_DRIVE⇒STDLIB.H
#define MAX_DIR		_MAX_DIR	//_MAX_DIR  ⇒STDLIB.H
#define MAX_FNAME	_MAX_FNAME	//_MAX_FNAME⇒STDLIB.H
#define MAX_EXT		_MAX_EXT	//_MAX_EXT  ⇒STDLIB.H
//⇒cliplibc.c
#define splitpath	internal_splitpath
#define makepath	internal_makepath
void splitpath(const char* path, char drive[/*MAX_DRIVE*/], char dir[/*MAX_DIR*/], char fname[/*MAX_FNAME*/], char ext[/*MAX_EXT*/]);
void makepath(char path[/*MAX_PATH*/], const char* drive, const char* dir, const char* fname, const char* ext);
/*--------------------------------------------------------------------------*/
//⇒cliplibc.c
size_t malloc_usable_size(void* ptr);
/*--------------------------------------------------------------------------*/
//⇒rand48.c
struct drand48_data {
	unsigned short	x[3];		//+ 0,6 Current state.					//┐
	unsigned short	a[3];		//+ 6,6 Factor in congruential formula.			//├lcong48()の引数param[7]の並びに一致
	unsigned short	c[1];		//+12,2 Additive constant in congruential formula.	//┘
	unsigned short	old_x[3];	//+14,6 Old state.
};					//=20
//Return non-negative, double-precision floating-point value in [0.0,1.0).
double drand48();
int    drand48_r(                         struct drand48_data* buffer, double* result);		//GNU extension
double erand48(  unsigned short xsubi[3]);
int    erand48_r(unsigned short xsubi[3], struct drand48_data* buffer, double* result);		//GNU extension
//Return non-negative, long integer in [0,2^31).
long lrand48();
int  lrand48_r(                         struct drand48_data* buffer, long* result);		//GNU extension
long nrand48(  unsigned short xsubi[3]);
int  nrand48_r(unsigned short xsubi[3], struct drand48_data* buffer, long* result);		//GNU extension
//Return signed, long integers in [-2^31,2^31).
long mrand48();
int  mrand48_r(                         struct drand48_data* buffer, long* result);		//GNU extension
long jrand48(  unsigned short xsubi[3]);
int  jrand48_r(unsigned short xsubi[3], struct drand48_data* buffer, long* result);		//GNU extension
//Seed random number generator.
void srand48(  long seedval);
int  srand48_r(long seedval,                        struct drand48_data* buffer);		//GNU extension
unsigned short* seed48(  unsigned short seed16v[3]);
int             seed48_r(unsigned short seed16v[3], struct drand48_data* buffer);		//GNU extension
void lcong48(  unsigned short param[7]);
int  lcong48_r(unsigned short param[7],             struct drand48_data* buffer);		//GNU extension
/*--------------------------------------------------------------------------*/
//⇒cliplibc.c
long a64l(const char* s);
char* l64a(long n);
int l64a_r(long n, char* buffer, int buflen);
void* bsearch_r(const void* key, const void* _base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void* arg);	//独自拡張
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define bsearch		internal_bsearch
void* bsearch(const void* key, const void* _base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
/*--------------------------------------------------------------------------*/
//⇒getsubopt.c
int getsubopt(char** optionp, char* const* tokens, char** valuep);	//第2引数は'const char* const* tokens'とするのが自然だと思うのだが、仕様で'char* const* tokens'となっているので仕方が無い。
/*--------------------------------------------------------------------------*/
//⇒clipsort.c
void qsort_r(void* base, size_t num, size_t width, int (*compare)(const void*, const void*, void*), void* arg);
int heapsort(void* base, size_t num, size_t width, int (*compare)(const void*, const void*));	//FreeBSD 10.0 June 4, 1993 FreeBSD 10.0
int heapsort_r(void* base, size_t num, size_t width, int (*compare)(const void*, const void*, void*), void* arg);	//独自拡張
int mergesort(void* base, size_t num, size_t width, int (*compare)(const void*, const void*));	//FreeBSD 10.0 June 4, 1993 FreeBSD 10.0
int mergesort_r(void* base, size_t num, size_t width, int (*compare)(const void*, const void*, void*), void* arg);	//独自拡張
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define qsort		internal_qsort
void qsort(void* base, size_t num, size_t width, int (*compare)(const void*, const void*));
/****************************************************************************
 *	include/string.h
 ****************************************************************************/
//⇒cliplibc.c
char* strtok_r(char* s1, const char* s2, char** saveptr);
char* mbstok(char* s1, const char* s2);				//Visual C++の  _mbstok()関数ではなく、自分で実装した  mbstok()関数を使用する事にしました。
char* mbstok_r(char* s1, const char* s2, char** saveptr);
char* strchrnul(const char* s, int c);
void* rawmemchr(const void* s, int c);
char* strsep(char** stringp, const char* delim);
char* strcasestr(const char* s1, const char* s2);
char* mbscasestr(const char* s1, const char* s2);
size_t strlcpy(char* dst, const char* src, size_t size);
size_t strlcat(char* dst, const char* src, size_t size);
int strcasecmp(const char* s1, const char* s2);
int strncasecmp(const char* s1, const char* s2, size_t n);
int mbscasecmp(const char* s1, const char* s2);
int mbsncasecmp(const char* s1, const char* s2, size_t n);
//size_t strnlen(const char* string, size_t n);
char* strndup(const char* string, size_t n);
//void* memccpy(void* dest, const void* src, int c, size_t n);
void* mempcpy(void* dest, const void* src, size_t n);
char* stpncpy(char* dest, const char* src, size_t n);
char* stpcpy(char* dest, const char* src);
int ffs(int i);
#define strdupa(s)	strndupa(s, -1)
#define strndupa(s, n)						\
	__strndupa_helper( (s) ,  (n) ,				\
	   alloca(strnlen( (s) ,  (n) ) + 1/*'\0'*/))
char* __strndupa_helper(const char* s, size_t n, void* p);
size_t mbsspn(const char* s1, const char* s2);
size_t mbscspn(const char* s1, const char* s2);
int mbsnextc(const char* s);
char* mbsinc(const char* s);
char* mbsninc(const char* s, size_t count);
char* mbsdec(const char* start, const char* current);
char* mbschr(const char* s, int c);
char* mbsstr(const char* s1, const char* s2);
char* mbspbrk(const char* s, const char* accept);
int strnextc(const char* s);
char* strinc(const char* s);
char* strninc(const char* s, size_t count);
char* strdec(const char* start, const char* current);
char* mbsupr(char* string);
char* mbslwr(char* string);
size_t mbslen(const char* string);
size_t mbsnlen(const char* string, size_t n);
int mbscmp(const char* s1, const char* s2);
int mbsncmp(const char* s1, const char* s2, size_t n);
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define strtok		internal_strtok
#define strstr		internal_strstr
#define strnlen		internal_strnlen
#define strncmp		internal_strncmp
#define strchr		internal_strchr
#define strrchr		internal_strrchr
#define memchr		internal_memchr
#define strspn		internal_strspn
#define strcspn		internal_strcspn
#define strpbrk		internal_strpbrk
#define strncat		internal_strncat
#define strupr		internal_strupr
#define strlwr		internal_strlwr
#define memccpy		internal_memccpy
#define strncpy		internal_strncpy
#define strtol		internal_strtol
#define strtoul		internal_strtoul
#define div		internal_div
#define ldiv		internal_ldiv
char* strtok(char* s1, const char* s2);
char* strstr(const char* s1, const char* s2);
size_t strnlen(const char* string, size_t n);
int strncmp(const char* s1, const char* s2, size_t n);
char* strchr(const char* s, int c);
char* strrchr(const char* s, int c);
void* memchr(const void* _s, int c, size_t n);
size_t strspn(const char* s1, const char* s2);
size_t strcspn(const char* s1, const char* s2);
char* strpbrk(const char* s, const char* accept);
char* strncat(char* dest, const char* src, size_t n);
char* strupr(char* string);
char* strlwr(char* string);
void* memccpy(void* dest, const void* src, int c, size_t n);
char* strncpy(char* dest, const char* src, size_t n);
long strtol(const char* nptr, char** endptr, int base);
unsigned long strtoul(const char* nptr, char** endptr, int base);
div_t div(int n, int d);
ldiv_t ldiv(long n, long d);
/*--------------------------------------------------------------------------*/
//⇒clipdire.c
int strverscmp(const char* s1, const char* s2);
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_STDW_X64_H__
