/* Copyright (C) 1996  TCX DataKonsult AB & Monty Program KB & Detron HB
   For a more info consult the file COPYRIGHT distributed with this file */
/*
  A better inplementation of the UNIX ctype(3) library.
  Notes:   global.h should be included before ctype.h
*/

#ifndef _m_ctype_h
#define _m_ctype_h

#define MY_CHARSET_BIG5		1
#define MY_CHARSET_CZECH	2
#define MY_CHARSET_DEC8		3
#define MY_CHARSET_DOS		4
#define MY_CHARSET_GERMAN1	5
#define MY_CHARSET_HP8		6
#define MY_CHARSET_KOI8_RU	7
#define MY_CHARSET_LATIN1	8
#define MY_CHARSET_LATIN2	9
#define MY_CHARSET_SWE7		10
#define MY_CHARSET_USA7		11
#define MY_CHARSET_UJIS		12
#define MY_CHARSET_SJIS		13

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef __WIN32__
#include <ctype.h>
#endif
#define _CTYPE_H	/* Don't include std ctype.h when this is included */

#ifndef CTYPE_LIBRARY
#define EXT extern
#define D(x)
#else
#define EXT
#define D(x)	= x
#endif

#define	_U	01	/* Upper case */
#define	_L	02	/* Lower case */
#define	_N	04	/* Numeral (digit) */
#define	_S	010	/* Spacing character */
#define	_P	020	/* Punctuation */
#define	_C	040	/* Control character */
#define	_B	0100	/* Blank */
#define	_X	0200	/* heXadecimal digit */

extern uchar NEAR ctype_@mystrings_charset@[];
extern uchar NEAR to_upper_@mystrings_charset@[];
extern uchar NEAR to_lower_@mystrings_charset@[];
extern uchar NEAR sort_order_@mystrings_charset@[];

#define my_ctype	ctype_@mystrings_charset@
#define my_to_upper	to_upper_@mystrings_charset@
#define my_to_lower	to_lower_@mystrings_charset@
#define my_sort_order	sort_order_@mystrings_charset@

#ifndef __WIN32__
#define	_toupper(c)	(char) my_to_upper[(uchar) (c)]
#define	_tolower(c)	(char) my_to_lower[(uchar) (c)]
#define toupper(c)	(char) my_to_upper[(uchar) (c)]
#define tolower(c)	(char) my_to_lower[(uchar) (c)]

#define	isalpha(c)	((my_ctype+1)[(uchar) (c)] & (_U | _L))
#define	isupper(c)	((my_ctype+1)[(uchar) (c)] & _U)
#define	islower(c)	((my_ctype+1)[(uchar) (c)] & _L)
#define	isdigit(c)	((my_ctype+1)[(uchar) (c)] & _N)
#define	isxdigit(c)	((my_ctype+1)[(uchar) (c)] & _X)
#define	isalnum(c)	((my_ctype+1)[(uchar) (c)] & (_U | _L | _N))
#define	isspace(c)	((my_ctype+1)[(uchar) (c)] & _S)
#define	ispunct(c)	((my_ctype+1)[(uchar) (c)] & _P)
#define	isprint(c)	((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B))
#define	isgraph(c)	((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N))
#define	iscntrl(c)	((my_ctype+1)[(uchar) (c)] & _C)
#define	isascii(c)	(!((c) & ~0177))
#define	toascii(c)	((c) & 0177)

#ifdef ctype
#undef ctype
#endif /* ctype */

#endif	// __WIN32__

/* Some macros that should be cleaned up a little */
#define isvar(c)	(isalnum(c) || (c) == '_')
#define isvar_start(c)	(isalpha(c) || (c) == '_')
#define tocntrl(c)	((c) & 31)
#define toprint(c)	((c) | 64)

/* Support for Japanese(UJIS) characters, by tommy@valley.ne.jp */
#if MY_CHARSET_CURRENT == MY_CHARSET_UJIS
#define USE_MB
#define	USE_MB_IDENT
#define isujis(c)	((0xa1<=(uchar)(c) && (uchar)(c)<=0xfe))
#define iskata(c)	((0xa1<=(uchar)(c) && (uchar)(c)<=0xdf))
#define isujis_ss2(c)	((unsigned char)(c) == 0x8e)
#define isujis_ss3(c)	((unsigned char)(c) == 0x8f)
#define ismbchar(p, end)	((*(uchar*)(p)<0x80)? 0:\
	isujis(*(p)) && end-(p)>1 && isujis(*((p)+1))? 2:\
	isujis_ss2(*(p)) && end-(p)>1 && iskata(*((p)+1))? 2:\
	isujis_ss3(*(p)) && end-(p)>2 && isujis(*((p)+1)) && isujis(*((p)+2))? 3:\
	0)
#define ismbhead(c)	(isujis(c) || isujis_ss2(c) || isujis_ss3(c))
#define mbcharlen(c)	(isujis(c)? 2: isujis_ss2(c)? 2: isujis_ss3(c)? 3: 0)
#define MBMAXLEN	3
#endif

/* Support for Japanese(SJIS) characters, by tommy@valley.ne.jp */
#if MY_CHARSET_CURRENT == MY_CHARSET_SJIS
#define USE_MB
#define USE_MB_IDENT
#define issjishead(c)	((0x81<=(uchar)(c) && (uchar)(c)<=0x9f) || (0xe0<=(uchar)(c) && (uchar)(c)<=0xfc))
#define issjistail(c)	((0x40<=(uchar)(c) && (uchar)(c)<=0x7e) || (0x80<=(uchar)(c) && (uchar)(c)<=0xfc))
#define ismbchar(p, end)	(issjishead(*(p)) && end-(p)>1 && issjistail(*(p))? 2: 0)
#define ismbhead(c)	issjishead(c)
#define mbcharlen(c)	(issjishead(c)? 2: 0)
#define MBMAXLEN	2
#endif

/* Support for Chinese(BIG5) characters, by jou@nematic.ieo.nctu.edu.tw */

#if MY_CHARSET_CURRENT == MY_CHARSET_BIG5
#undef USE_BIG5CODE
#undef USE_STRCOLL
#define USE_BIG5CODE
#define USE_STRCOLL
#define isbig5head(c)   ((((char)c) >= '\xA1') && (((char)c) <= '\xF9'))
#define isbig5tail(c)   (((((char)c) >= '\x40')&& (((char)c) <= '\x7E')) \
			 || ((((char)c) >= '\xA1')&&(((char)c) <= '\xFE')))
#define isbig5code(c,d) (((((char)c) >= '\xA1') && (((char)c) <= '\xF9')) \
                         && (((((char)d) >= '\x40')&& (((char)d) <= '\x7E')) \
			 || ((((char)d) >= '\xA1')&&(((char)d) <= '\xFE'))))
#endif

/* Define, how much will the string grow under strxfrm */
#if MY_CHARSET_CURRENT == MY_CHARSET_CZECH
#undef USE_STRCOLL
#define USE_STRCOLL
#endif

#ifdef USE_STRCOLL
extern uint MY_STRXFRM_MULTIPLY;
extern int my_strnxfrm(unsigned char *, unsigned char *, int, int);
extern int my_strnncoll(const unsigned char *, int, const unsigned char *, int);
extern int my_strxfrm(unsigned char *, unsigned char *, int);
extern int my_strcoll(const unsigned char *, const unsigned char *);
extern my_bool my_like_range(const char *ptr,uint ptr_length,pchar escape,
			     uint res_length, char *min_str,char *max_str);
#endif

#ifdef	__cplusplus
}
#endif

#endif /* _m_ctype_h */
