    /********************************************************/
    /*                                                      */
    /*                                                      */
    /*         Copyright (C), 1993  SEIKO EPSON Corp.       */
    /*         ALL RIGHTS RESERVED                          */
    /*                                                      */
    /*                                                      */
    /*  file name : stdlib.h                                */
    /*                                                      */
    /*  Revision history                                    */
    /*      93/12/17    first release       S.Akaiwa        */
    /*      97/02/20    modified            T.Katahira      */
    /*                  change function declaration         */
    /*                          to the ANSI style           */
    /*      00/06/01    modified            M.Kakinuma      */
    /*      14/11/19    modify for P/ECE    Naoyuki Sawa    */
    /*                - qsort_r()を追加しました。実装はclipsort.cにあります。 */
    /*      15/01/07    modify for P/ECE    Naoyuki Sawa    */
    /*                - splitpath(),makepath()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。 */
    /*                - malloc_usable_size()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。                            */
    /*                  malloc_usable_size()は本当はmalloc.hで宣言すべきなのですが、P/ECEにはmalloc.hが無いのでinclude/stdlib.hで宣言することにしました。 */
    /*      15/01/20    modify for P/ECE    Naoyuki Sawa    */
    /*                - size_tの定義をunsigned型に統一しました。 */
    /*      15/04/05    modify for P/ECE    Naoyuki Sawa    */
    /*                - gcc33のabs()最適化バグを回避するためのマクロを定義しました。                 */
    /*                  詳細はP/ECE研究記録2015/04/05「gcc33 abs()の最適化バグ」を参照してください。 */
    /*      15/04/25    modify for P/ECE    Naoyuki Sawa    */
    /*                - rand48ファミリの関数宣言を追加しました。実装は、rand48.cに有ります。 */
    /*                                                      */
    /********************************************************/

#ifndef _STDLIB_H
#define _STDLIB_H

#ifndef _SIZE_T
#define _SIZE_T
//{{2015/01/20変更:size_tの定義をunsigned型に統一しました。
//typedef unsigned long   size_t;     /* size of type */
//↓2015/01/20変更:size_tの定義をunsigned型に統一しました。
// * Tue Jan 20 23:26:57 JST 2015 Naoyuki Sawa
// - P/ECE開発環境ではsize_tはunsigned。unsigned longではない。
//   例1:○
//   │typedef unsigned size_t;
//   │extern void* memcpy(void*,const void*,size_t); ← 警告無くコンパイル出来る
//   例2:×
//   │typedef unsigned long size_t;
//   │extern void* memcpy(void*,const void*,size_t); ← warning:conflicting types for built-in function `memcpy'
//   P/ECE開発環境の標準インクルードファイルも間違っているので要注意です。
//   stddef.hでの定義は正しいけれど、stdio.h,stdlib.h,string.h,time.hでの定義は間違っています。
//   たまたまstddef.hを最初にインクルードすると大丈夫なのでした。
// - どのヘッダファイルを最初にインクルードしても大丈夫なように、定義を統一することにしました。
//   自作のP/ECEプログラムならば、stddef.hを最初にインクルードするようにできるのですが、
//   オープンソースのライブラリを変更無くコンパイルしたい時に、stddef.h以外が最初になっている場合があるからです。
//   具体的には、/clip/liblua/をコンパイルするときに警告が出て、この問題に気付きました。
typedef unsigned size_t;
//}}2015/01/20変更:size_tの定義をunsigned型に統一しました。
#endif

#ifndef _WCHAR_T
#define _WCHAR_T
typedef unsigned short  wchar_t;    /* wide character type */
#endif
    
typedef struct {                    /* division type */
  int rem;
  int quot; } div_t;

typedef struct {                    /* long division type */
  long rem;
  long quot; } ldiv_t;

#if !defined(NULL)
#  define NULL          ((void *)0L)/* null pointer */
#endif

#define RAND_MAX        0x7fff      /* random maximum number */

#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0

/*  global, memory allocation proc.*/
extern unsigned char *ansi_ucStartAlloc;   /* allocate area, start address */
extern unsigned char *ansi_ucEndAlloc;     /* allocate area, end address   */
extern unsigned char *ansi_ucNxtAlcP;      /* next allocate address        */
extern unsigned char *ansi_ucTblPtr;       /* next address for table       */
extern unsigned long ansi_ulRow;           /* table count   */


extern  unsigned int    seed;       /* random seed */

typedef int fn_t( const void *, const void * );


/* prototype definition */

extern  void            abort( void );
extern  void            exit( int ); 
extern  int             atexit( void (*)(void) );
extern  char *          getenv( const char * );
extern  int             system( const char * );

extern  void *          malloc( size_t );
extern  void *          calloc( size_t, size_t );
extern  void *          realloc( void *, size_t );
extern  void            free( void * ); 
extern  int             ansi_InitMalloc(unsigned long, unsigned long);

extern  int             atoi( const char * );
extern  long            atol( const char * );
extern  double          atof( const char * );
extern  long            strtol( const char *, char **, int );
extern  unsigned long   strtoul( const char *, char **, int );
extern  double          strtod( const char *, char ** );

extern  int             abs( int );
extern  long            labs( long );
//{{2015/04/05追加:gcc33のabs()最適化バグを回避するためのマクロを定義しました。詳細はP/ECE研究記録2015/04/05「gcc33 abs()の最適化バグ」を参照してください。
#define abs(x) ({					\
	int __x__ = (x);				\
	asm /*volatile*/ (				\
		"cmp  %0, 0  \n"			\
		"jrge 3      \n"			\
		" not %0, %0 \n"			\
		" add %0, 1  \n"			\
		: "=r"(__x__) : "0"(__x__) : "cc");	\
	__x__; })
#define labs(x) abs(x)
//}}2015/04/05追加:gcc33のabs()最適化バグを回避するためのマクロを定義しました。詳細はP/ECE研究記録2015/04/05「gcc33 abs()の最適化バグ」を参照してください。

extern  div_t           div( int, int );
extern  ldiv_t          ldiv( long, long );

extern  int             rand( void );
extern  void            srand( unsigned int );

extern  void *          bsearch( const void *, const void *, 
                        size_t, size_t, fn_t * );

extern  void            qsort( void *, size_t, size_t, fn_t * );
//{{2014/11/19追加:qsort_r()を追加しました。実装はclipsort.cにあります。
void qsort_r(void* base, size_t num, size_t width, int (*compare)(const void*, const void*, void*), void* arg);
//}}2014/11/19追加:qsort_r()を追加しました。実装はclipsort.cにあります。

//{{2015/01/07追加:splitpath(),makepath()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。
/* Windowsの、パス名構成要素分解/合成関数です。
 * P/ECEでも、ファイル名と拡張子の分解/合成は便利なので、定義しておくことにしました。
 * - MAX_PATH,MAX_DRIVE,MAX_DIR,MAX_FNAME,MAX_EXTは、Windowsと同じ値としました。
 *   path[MAX_PATH],drive[MAX_DRIVE],dir[MAX_DIR],fname[MAX_FNAME],ext[MAX_EXT]を全てスタック上に確保すると、
 *   合計1KB強必要なので、スタックオーバーフローに注意してください。
 *   P/ECEでは、drive[MAX_DRIVE]とdir[MAX_DIR]は通常必要ないので、これら2つを確保しなければ少し節約できます。 */
#define MAX_PATH  260
#define MAX_DRIVE 3
#define MAX_DIR   256
#define MAX_FNAME 256
#define MAX_EXT   256
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);
//}}2015/01/07追加:splitpath(),makepath()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。

//{{2015/01/07追加:malloc_usable_size()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。malloc_usable_size()は本当はmalloc.hで宣言すべきなのですが、P/ECEにはmalloc.hが無いのでinclude/stdlib.hで宣言することにしました。
//{{2014/09/29追加:malloc_usable_size()を追加しました。
//ヒープに割り当てられたメモリブロックのサイズを取得します。
// - この関数は、GNU拡張です。便利なので、P/ECEにも追加することにしました。
// - Visual C++にも、似た関数として_msize()が有りますが、少し仕様が異なっています。
//   malloc_usable_size()にNULLポインタを渡すと、正常に(0)が返されます。
//   _msize()にNULLポインタを渡すと、不正終了します。
//   malloc_usable_size()の方が安全なので、malloc_usable_size()の仕様に従いました。
//□「Linux Programmer's Manual」より引用
//│MALLOC_USABLE_SIZE(3)      Linux Programmer's Manual     MALLOC_USABLE_SIZE(3)
//│NAME
//│       malloc_usable_size - obtain size of block of memory allocated from heap
//│SYNOPSIS
//│       #include <malloc.h> 
//│       size_t malloc_usable_size (void *ptr);
//│DESCRIPTION
//│       The malloc_usable_size() function returns the number of usable bytes in
//│       the block pointed to by ptr, a pointer to a block of  memory  allocated
//│       by malloc(3) or a related function.
//│RETURN VALUE
//│       malloc_usable_size() returns the number of usable bytes in the block of
//│       allocated memory pointed to by ptr.  If ptr is NULL, 0 is returned.
//│CONFORMING TO
//│       This function is a GNU extension.
//│NOTES
//│       The value returned by malloc_usable_size()  may  be  greater  than  the
//│       requested  size of the allocation because of alignment and minimum size
//│       constraints.  Although the excess  bytes  can  be  overwritten  by  the
//│       application without ill effects, this is not good programming practice:
//│       the number of excess bytes in an allocation depends on  the  underlying
//│       implementation.
//│       The main use of this function is for debugging and introspection.
//│SEE ALSO
//│       malloc(3)
//│COLOPHON
//│       This  page  is  part of release 3.53 of the Linux man-pages project.  A
//│       description of the project, and information about reporting  bugs,  can
//│       be found at http://www.kernel.org/doc/man-pages/.
//│GNU                               2012-03-29             MALLOC_USABLE_SIZE(3)
size_t malloc_usable_size(void* ptr);
//}}2014/09/29追加:malloc_usable_size()を追加しました。
//}}2015/01/07追加:malloc_usable_size()の宣言をclippce.h⇒include/stdlib.hへ，実装をclippce.c⇒cliplibc.cへ移動しました。malloc_usable_size()は本当はmalloc.hで宣言すべきなのですが、P/ECEにはmalloc.hが無いのでinclude/stdlib.hで宣言することにしました。

//{{2015/04/25追加:rand48ファミリの関数宣言を追加しました。実装は、rand48.cに有ります。
// - drand48(),  erand48(),  lrand48(),  nrand48(),  mrand48(),  jrand48(),  srand48(),  seed48(),  lcong48()  はPOSIX.1-2001準拠です。
//   drand48_r(),erand48_r(),lrand48_r(),nrand48_r(),mrand48_r(),jrand48_r(),srand48_r(),seed48_r(),lcong48_r()はGNU拡張です。
// - □参照資料
//   │Linux Programmer's Manual (3) - DRAND48   (http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/drand48.3.html)
//   │Linux Programmer's Manual (3) - DRAND48_R (http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/drand48_r.3.html)
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
//}}2015/04/25追加:rand48ファミリの関数宣言を追加しました。実装は、rand48.cに有ります。

#endif  _STDLIB_H

