#ifdef __cplusplus
extern "C" {
#endif
/*
 *		AIX/370
 *		5713-AFL
 *	LICENSED MATERIALS - PROPERTY OF IBM
 *	(c) Copyright IBM Corporation 1989, 1990
 *	(c) Copyright Locus Computing Corporation 1989, 1990
 *	All Rights Reserved
 */

#ifndef H_SCCSID
#include <sccs.h>
#endif /* ~H_SCCSID */
H_SCCSID(@(#)NLchar.h	16.25	AIX)	/* Modified 3/17/92 17:39:03 */
#if 0
/* (MRL) NLchar, and constants are used in ctab.h, so they need to be defined before ctab.h is
	included. <stddef.h> is needed for wchar_t*/
#ifdef _MBCS
#include <stddef.h> 
typedef wchar_t NLchar;
#else
typedef unsigned short NLchar;
#endif
#define NLCHARMAX       13000
#define NLCTABMAX       (NLCHARMAX+1)   /* allow for EOF as input value */
#define NLCTBITMX       ((NLCTABMAX+7)/8) /* bytes for NLCTABMAX-sized bitmap */

/* (MRL) End of additions */
#endif
#include <ctab.h>

#ifndef _h_NLCHAR
#define _h_NLCHAR

#ifdef _MBCS

#include <mbcs.h>

/*  BASIC DEFINITIONS FOR USING NLCHARS.
 */

/*  The big type itself.
 */

typedef wchar_t NLchar;
typedef unsigned char  UCHAR;

/*  Number of distinct NLchars.
 */
#define NLCHARMAX	13000	

#ifdef lint
extern NLchar NCdechr();
#else

/*  Single-shift character definition (both NLchar and char representation).
 */
#define	NCisshift(c)	0

/*  SINGLE-CHARACTER CONVERSION MACROS.
 */

/*  Internal macro to test for multi-byte NLS code point.
 */
#define	_NCis2(c0, c1)	(_mb_in_tbl->th_chlen_tbl[(unsigned int)(c0)] == 2)

extern char __temp_ch[];
extern int __c_temp;

/*  Internal macro to convert multi-byte NLS code point to NLchar.
 */
#define _NCd2(c0, c1)  \
		(__temp_ch[0] = (c0) , __temp_ch[1] = (c1) , \
	         (_mbtowc((wchar_t *)&__c_temp, __temp_ch, MB_CUR_MAX)) > 0 ? \
		 (NLchar) __c_temp : (NLchar)'\0')


/*  Internal macro to convert NLchar to NLS code point.
 */
#define _NCe2(nlc, c0, c1)	\
		 ((_wctomb(__temp_ch, (nlc))) <= 0 ? ((c0) = 0, 0) : \
		  (_mblen(__temp_ch, MB_CUR_MAX)) == 1 ? \
		  ((c0) = __temp_ch[0], 1) : \
		  ((c0) = __temp_ch[0], (c1) = __temp_ch[1], 2))

/*  Convert 1 or 2 chars to an NLchar and return it.
 */
#define NCdechr(c)		\
		((_mbtowc((wchar_t *)&__c_temp, (c), MB_CUR_MAX) > 0) ? \
		 (NLchar) __c_temp : (NLchar)'\0')

/*  Convert c0 (and c1, if need be) into NLchar nlc; return # chars used.
 */
#define _NCdec2(c0, c1, nlc)			\
		(__temp_ch[0] = (c0) , __temp_ch[1] = (c1), \
		 (_mbtowc(&(nlc), __temp_ch, MB_CUR_MAX)) )

/*  Convert a mutibyte char and store into a NLchar pointed to by nlc;
 *  return # bytes that comprise the multibyte character.
 */
#define NCdec(c, nlc)	(((c) == NULL) ? 0 :  \
				(((*(c)) == '\0') ? (*(nlc)) = (NLchar)'\0', \
				1 : (_mbtowc((nlc), (c), MB_CUR_MAX))))

/*  Convert a NLchar and store into a multibyte char; return # bytes that
 *  comprise the multibyte character
 */
#define NCenc(nlc, c)	(((c) == NULL) ? 0 : (_wctomb((c), (*(nlc)))))

/*  CODE POINT UTILITY MACROS.
 */

/*  Return length of wide char nlc if encoded into multibyte char.
 */
#define NCchrlen(nlc)	\
		(_wctomb(__temp_ch, (nlc)))

/*  Indicate if c points to an NLS code point; return length if so.
 */
#define NLisNLcp(c)	\
	(isascii(*(c)) ? 0 :(__c_temp=_mblen(c, MB_CUR_MAX)) >= 1 ? __c_temp:0)

/*  Return length of in bytes of the character starting at c.
 */
#define NLchrlen(c)	\
		(_mblen(c, MB_CUR_MAX))	
#endif					/* lint is not defined */


/*  CHARACTER COLLATING/CLASSIFICATION INFO.
 */

/*  Struct for character collating/classification tables.
 */
#define NLCTMAG0	(unsigned char)0x01
#define NLCTMAG1	(unsigned char)0x05

#define NLCTABMAX	(NLCHARMAX+1)	/* allow for EOF as input value */
/* the reason it is devided by 8, is because each map is a UCHAR, which is
 *  8 bits.  That means we can use a UCHAR to map 8 characters.  The total
 *  number of characters is devided by the number possble maping places in
 *  a UCHAR.
 *  The reason behind the modulation, is to make sure we round it up to where
 *  it can be divisible by 8, with no fractions.
 */
#define NLCTBITMX	((NLCTABMAX+(8-NLCTABMAX%8))/8) /* bytes for NLCTABMAX-sized bitmap */


/*  Struct for extended collating descriptors.
 */
struct NLcoldesc {
	short	cd_stroff;	/* offset to special string */
	short	cd_cval;	/* collating value */
	short	cd_coluniq;	/* unique collating value */
};

#ifndef lint
/*  Defs for accessing collating data.
 */
extern 	struct NLctab _MB_ctab[1] ;

int strcoll(const char *, const char *);
int strncoll(const char *, const char *, size_t);
int strxfrm(char *, const char *, size_t);
int wcscoll(const wchar_t *, const wchar_t *);
int wcsncoll(const wchar_t *, const wchar_t *, size_t);
int _mbxcol (int, unsigned char **, wchar_t **);
int _mbxcolu(int, unsigned char ** , wchar_t **);
int _wcxcol (int, wchar_t **, wchar_t **);
int _wcxcolu(int, wchar_t **, wchar_t **);

#define wc_collate(c)	 (_MB_ctab->ct_collate[__wcindx(c)+1])
#define wc_coluniq(c)	 (_MB_ctab->ct_coluniq[__wcindx(c)+1])
#define wc_eqvmap(ucval) ((_MB_ctab->ct_eqvmap)[(ucval) + 1 >> 3] & \
				(1 << (((ucval) + 1) & 7)))

#define NCcollate(nlc)	wc_collate(nlc)
#define NCcoluniq(nlc)	wc_coluniq(nlc)
#define NCeqvmap(ucval)	wc_eqvmap(ucval)

#define NCdecstr(c, nlc, len) ( (int)(mbstowcs(nlc, (const char *)c, len)) )

#define NCdecode(s, wcs)						\
	((__c_temp = _mbtowc(wcs, (const char *)s, MB_CUR_MAX)) <= 0 ?	\
		((*(wcs)) = (NLchar)*s, 1)				\
	:								\
		__c_temp )

#define NCencode(wcs, s)						\
	(( __c_temp = _wctomb(s, *(wcs))) <= 0 ?			\
		((*(s)) = *(char *)(wcs), 1)				\
	:								\
		__c_temp )


#ifdef __AIX 
#define mbscoll		strcoll
#define mbsncoll	strncoll
#endif /* __AIX */

#endif					/* is not defined */

extern struct NLcoldesc *_NLcoldesc;
extern void NLgetctab();
extern int NLgetfile();

/*  MISCELLANY.
 */

/*  Internal defs for string(3) macros using charsets.
 */
#define NLCSETMAX	33	/* malloc charsets over this length - 1 */

#ifdef lint
extern NLchar *_NCbufstr();
extern void _NCfreebuf();
#else

/*  Decode a string into an NLchar array big enough to hold it.  Use array
 *  s if possible, else malloc one with _NLgetbuf.  First element flags
 *  whether malloc was used.
 */
#define _NCbufstr(s, d, l)	((d)[0] = 0, ((l) - 1 <= \
					NCdecstr((s), &(d)[1], (l) - 1)) ? \
					_NCgetbuf((s), (l)) : &(d)[1])

/*  Free a buffer filled by _NCbufstr, if it was malloc'd originally.
 */
#define _NCfreebuf(s)		if (*((s) - 1)) free((s) - 1);
#endif					/* is not defined */

extern NLchar *_NCgetbuf();
extern void free(void*);	// (MRL) Added prototype

#else  /* _MBCS not defined ==> 1.2 header */

/*  BASIC DEFINITIONS FOR USING NLCHARS.
 */

/*  The big type itself.
 */
typedef unsigned short NLchar;
typedef unsigned char  UCHAR;

/*  Number of distinct NLchars.
 */
#define NLCHARMAX	768

#ifdef lint
extern NLchar NCdechr();
#else

/*  Single-shift character definition (both NLchar and char representation).
 */
#define	NCisshift(c)	(((c) & ~3) == 0x1c)

/*  SINGLE-CHARACTER CONVERSION MACROS.
 */

/*  Internal macro to test for multi-byte NLS code point.
 */
#define _NCis2(c0, c1)	(NCisshift(c0) && (c1) & 0x80)

/*  Internal macro to convert multi-byte NLS code point to NLchar.
 */
#define _NCd2(c0, c1)	(0x21 - (UCHAR)(c0) << 7 | (c1) & 0x7f)

/*  Internal macro to convert NLchar to NLS code point.
 */
#define _NCe2(nlc, c0, c1)	((0xff < (nlc)) ? \
					((c0) = 0x21 - ((nlc) >> 7), \
						(c1) = (nlc) | 0x80, 2) : \
					((c0) = (UCHAR)(nlc), 1))

/*  Convert 1 or 2 chars to an NLchar and return it.
 */
#define NCdechr(c)	((_NCis2((c)[0], (c)[1])) ? \
				_NCd2((c)[0], (c)[1]) : (c)[0])

/*  Convert c0 (and c1, if need be) into NLchar nlc; return # chars used.
 *  This is the only conversion macro that accepts an NLchar, rather than
 *  a pointer to one, as an argument.
 */
#define _NCdec2(c0, c1, nlc) ((_NCis2((c0), (c1))) ? \
				((nlc) = _NCd2((c0), (c1)), 2) : \
				((nlc) = (UCHAR)(c0), 1))

/*  Convert 1 or 2 chars and store into an NLchar pointed to by nlc;
 *  return # chars converted.
 */
#define NCdec(c, nlc)	(_NCdec2((c)[0], (c)[1], (nlc)[0]))

/*  Convert an NLchar and store into 1 or 2 chars; return # chars produced.
 */
#define NCenc(nlc, c)	(_NCe2((nlc)[0], (c)[0], (c)[1]))

/*  CODE POINT UTILITY MACROS.
 */

/*  Return length of NLchar nlc if encoded into char(s).
 */
#define NCchrlen(nlc)	(((nlc) <= 0xff) ? 1 : 2)

/*  Indicate if c points to an NLS code point; return length if so.
 */
#define NLisNLcp(c)	(((c)[0] & 0x80) ? 1 : (_NCis2((c)[0], (c)[1])) ? 2 : 0)

/*  Return length of "character" at c.
 */
#define NLchrlen(c)	((_NCis2((c)[0], (c)[1])) ? 2 : 1)
#endif

/*  CHARACTER COLLATING/CLASSIFICATION INFO.
 */

/*  Struct for character collating/classification tables.
 */
#define NLCTMAG0	(unsigned char)0x01
#define NLCTMAG1	(unsigned char)0x05

#define NLCTABMAX	(NLCHARMAX+1) 	/* allow for EOF as input value */
#define NLCTBITMX	((NLCTABMAX+7)/8) /* bytes for NLCTABMAX-sized bitmap */

/*  Struct for extended collating descriptors.
 */
struct NLcoldesc {
	short	cd_stroff;	/* offset to special string */
	short	cd_cval;	/* special collating value */
};

#ifndef lint
/*  Defs for accessing collating data.
 */
#define NCcollate(nlc)	((_NLctab->ct_collate+1)[(nlc)])
#define NCcoluniq(nlc)	((_NLctab->ct_coluniq+1)[(nlc)])
#define NCeqvmap(ucval)	((_NLctab->ct_eqvmap)[(ucval) + 1 >> 3] & \
				(1 << ((ucval) + 1 & 7)))
#endif

extern struct NLcoldesc *_NLcoldesc;
extern void NLgetctab();
extern int NLgetfile();
#ifndef KERNEL
static struct NLctab **NLSused = &_NLctab;	/* indicate use of NLS */
static struct NLctab **_NLSused = &_NLctab;	/* indicate use of NLS */
#endif /* ! KERNEL */

/*  MISCELLANY.
 */

/*  Internal defs for string(3) macros using charsets.
 */
#define NLCSETMAX	33	/* malloc charsets over this length - 1 */

#ifdef lint
extern NLchar *_NCbufstr();
extern void _NCfreebuf();
#else

/*  Decode a string into an NLchar array big enough to hold it.  Use array
 *  s if possible, else malloc one with _NLgetbuf.  First element flags
 *  whether malloc was used.
 */
#define _NCbufstr(s, d, l)	((d)[0] = 0, ((l) - 1 <= \
					NCdecstr((s), &(d)[1], (l) - 1)) ? \
					_NCgetbuf((s), (l)) : &(d)[1])

/*  Free a buffer filled by _NCbufstr, if it was malloc'd originally.
 */
#define _NCfreebuf(s)		if (*((s) - 1)) free((s) - 1);
#endif

extern NLchar *_NCgetbuf();
extern void free(void*);		// (MRL) Added prototype

#endif  /* _MBCS */

#endif /*_h_NLCHAR */
#ifdef __cplusplus
}
#endif
