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

#ifndef H_SCCSID
#include <sccs.h>
#endif /* ! H_SCCSID */
H_SCCSID(@(#)mbcs.h	1.9	AIX)	/* Modified: 19:01:41 10/19/90 */

#ifndef _h_MBCS
#define _h_MBCS

/*
 * OK, mbcs.h needs 2 things out of stddef.h (wchar_t and size_t).  So,
 * we'll include it here.  Right now, stddef.h does not define _h_STDDEF,
 * but it shouldn't be too bad since it's a very small file.
 */
#include <stddef.h>
#include <datarep.h>

/*
 * Header file for MBCS routines
 */

/* Misc defines */
#define MB_VERSION	"MB1"		/* Version number */
#define MB_MAXCSNAME	12		/* Max length of name of code page */

/* Flag definitions for ih_flags */
#define MB_IH_DIRECT	 0x0010	/* Input the character directly */
#define MB_1BYTE	 0x0001	/* input hdr ranges containing 1 byte chars */
#define MB_2BYTE	 0x0002	/* input hdr ranges containing 2 byte chars */
#define MB_3BYTE	 0x0004	/* input hdr ranges containing 3 byte chars */
#define MB_4BYTE	 0x0008	/* input hdr ranges containing 4 byte chars */
#define MB_IH_MBLEN_MASK 0x000F	/* length of multibyte char described by */
				/* the input header			 */

/* Flag definitions for oh_flags */
#define MB_OH_DIRECT_CELL	0x0001	/* Output the cell directly */
#define MB_OH_DIRECT_ROW	0x0002	/* Output the row directly */
#define MB_OH_TABLE_4B		0x0004	/* The table entries are 4 bytes long */

/* Flag definitions for ot_flags */
#define MB_OT_HAS_2B	0x01	/* This character has a 2 byte form */

/*
 * Local typedefs used by mb routines.
 */
typedef struct mb_tbl_hdr *tbl_ptr;

/*
 * Typedefs specific to mbcs.
 */
typedef unsigned long mbchar_t;

/*
 * This is a per character conversion entry structure.  It is used in the
 * output conversion table.
 */
struct mb_out_conv {
	unsigned char ot_flags;
	unsigned char ot_char;
	unsigned char ot_2chars[2];
};

/*
 * Structures used for input character translation tables (i.e. file code
 * to process code conversion).
 */
struct mb_in_hdr {
	union {
		struct mb_in_hdr *ihu_next;	/* Next input table */
		unsigned long ihu_offset;	/* Offset in file */
	} ih_un;
	unsigned short	ih_flags;	/* Flags (see below) */
	unsigned char	ih_start_code;	/* First code handled by this table */
	unsigned char	ih_end_code;	/* Last code handled by this table */
	unsigned char	ih_db_start;	/* double byte start code */
	unsigned char	ih_db_end;	/* double byte end code */
	unsigned char	ih_dispwidth;	/* disp width for chars in this range */
	unsigned long	ih_char_bias;	/* Bias for direct translations */
	wchar_t		ih_table[2];	/* Table contents (memory) */
};
#define __ih_next	ih_un.ihu_next
#define __ih_offset	ih_un.ihu_offset

/*
 * Structures used for input character translation tables (i.e. file code
 * to process code conversion).
 */
struct mb_out_hdr {
	union {
		struct mb_out_hdr *ohu_next;	/* Next output table */
		unsigned long ohu_offset;	/* Offset in file */
	} oh_un;
	unsigned short	oh_flags;	/* Flags (see below) */
	unsigned long	oh_start_code;	/* First code handled by this table */
	unsigned long	oh_end_code;	/* Last code handled by this table */
	unsigned long	oh_char_bias;	/* Bias for direct translations */
	char		oh_table[4];	/* Table contents (memory) */
};
#define oh_next		oh_un.ohu_next
#define oh_offset	oh_un.ohu_offset

/*
 * Table header for loaded table access
 */
struct mb_tbl_hdr {
	struct mb_in_hdr   *th_input;		/* First input table */
	struct mb_out_hdr  *th_output;		/* First output table */
	short		   th_mb_cur_max;	/* max size of multibyte char */
	short		   th_default;		/* default character */
	char		   th_magic[4];		/* magic string "MB1" */
	char		   th_name[MB_MAXCSNAME];	/* name of code set */
	char		   th_chlen_tbl[256];	/* for quickie _mblen lookup */
	char		   th_displen_tbl[256];	/* for quickie display width */
						/* lookup		     */
};

/*
 * Equivalent to mb_tbl_hdr, except that this is used in the file.  It omits
 * some fields that are calculated at load time so the table file is more
 * compact.
 */
struct mb_file_hdr {
	datarep_t	fh_datarep;		/* data representation tag */
	char		fh_magic[4];		/* "MB1" */
	short		fh_num_in_hdrs;		/* Number of input headers */
	short		fh_num_out_hdrs;	/* Number of output headers */
	short		fh_default;		/* default character */
};


/*
 * Macro definitions of some of the mbcs routines.  In general, these
 * routines do little error/boundary checking.
 */

/*
 * _mbdwidth(chptr)
 *
 * Like mbdwidth(), this will return the displaywidth of the first character
 * in the string pointed to by chptr.
 *
 * Currently, _mbdwidth() only uses the first byte to index into the
 * displen_tbl of the character table header, so it cannot detect bogus
 * mbchars where the first byte is a valid part of some character, but
 * the second byte is invalid.
 */
#define _mbdwidth(chptr) \
	( \
	    chptr == NULL ? -1 : \
	    (*((unsigned char *)chptr) == '\0' ? 0 : \
	    _mb_in_tbl->th_displen_tbl[*((unsigned char *)chptr)]) \
	)

/*
 * _mblen(chptr, n)
 *
 * Like mblen(), this will return the number of bytes of the first character
 * in the string pointed to by chptr.
 *
 * Currently, _mblen() only uses the first byte to index into the chlen_tbl
 * of the character table header, so it cannot detect bogus mbchars where the
 * first byte is a valid part of some character, but the second byte is invalid.
 */
#define _mblen(chptr, n) \
	( \
	    chptr == NULL ? 0 : \
	    (*((unsigned char *)chptr) == '\0' ? 0 : \
	    (((__c_temp = _mb_in_tbl->th_chlen_tbl[*((unsigned char *)chptr)]) <= n) ? \
	    __c_temp : -1)) \
	)

/*
 * _mbsadvance(chptr)
 *
 * Like mbsadvance(), this will return a pointer to the next character
 * in the string chptr, that is it will skip over the first char in chptr.
 *
 * Currently, _mbsadvance() only uses the first byte to index into the chlen_tbl
 * of the character table header, so it cannot detect bogus mbchars where the
 * first byte is a valid part of some character, but the second byte is invalid.
 */
#define _mbsadvance(chptr) \
	( \
	    chptr == NULL ? NULL : \
	    (__c_temp = _mb_in_tbl->th_chlen_tbl[*((unsigned char *)chptr)]) <= 0 \
	    ? NULL : \
	    ((char *)chptr + __c_temp) \
	)
#ifdef __cplusplus
#include <string.h>
#endif

#define	_mbscmp(s1,s2)		(_CLOCALE ? strcmp(s1,s2) : mbscmp(s1,s2))
#define	_mbsinvalid(s)		(_CLOCALE ? (char *) 0 : mbsinvalid(s))
#define	_mbslen(s)		(_CLOCALE ? strlen(s) : mbslen(s))

#ifndef	lint			/*** lint does not understand proto-types ***/

/*
 * Extern data objects
 */
extern struct mb_tbl_hdr *_mb_in_tbl; /* input table for translations */
extern struct mb_tbl_hdr *_mb_out_tbl; /* output table for translations */

/*
 * Extern function declarations
 */


extern	struct mb_tbl_hdr _MB_din_tbl[] ;

extern	int		__c_temp;


#define	_CLOCALE	( _mb_in_tbl == _MB_din_tbl )


#define	_wctomb(cp, wc)	((!((__c_temp = (int) (wc)) & ~0x7f)) || _CLOCALE ?   \
		( *(cp) = (char)(__c_temp), 1 ) : \
		wctomb(cp, (wchar_t)(__c_temp)))

/*
cp may be evaluated more than once in this macro.  Thus a construct such
as *ptr++ for the argument of cp would cause grief.  However, it was
determined that such constructs are not logical in the scope of MBCS so
this macro is used despite that.  -cjk,sn,cl-
The option of using __c_temp is not valid because macros that call 
_mbtowc already use __c_temp.
*/
#define	_mbtowc(wcp, cp, len)	( _CLOCALE || (!((*(cp)) & ~0x7f)) ?	 \
		( *(wcp) = (wchar_t) *(cp), 1 ) :   \
		mbtowc(wcp, cp, len))

		/* Multi-byte Character Proto-Types */

extern struct	mb_tbl_hdr *_mbgettab(char *);
extern void	_mb_freetab(struct mb_tbl_hdr *);
extern char	*mbsinvalid(char *);
extern char	*mbsadvance(char *);
extern int	mbstomb(mbchar_t *, char *, size_t);
extern char	*mbscat(char *, const char *);
extern char	*mbsncat(char *, const char *, size_t);
extern char	*mbscpy(char *, const char *);
extern char	*mbsncpy(char *, const char *, size_t);
extern char	*mbschr(const char *, mbchar_t);
extern char	*mbsrchr(const char *, mbchar_t);
extern char	*mbspbrk(const char *, const char *);
extern char	*mbstok(char *, const char *);

extern int	mbtowc(wchar_t *, const char *, size_t);
extern size_t	mbstowcs(wchar_t *, const char *, size_t);
extern size_t	mbslen(const char *);
extern int	mblen(const char *, size_t);
extern int	mbdwidth(const char *);
extern size_t	mbsspn(const char *, const char *);
extern size_t	mbscspn(const char *, const char *);
extern int	mbscmp(const char *, const char *);
extern int	mbsncmp(const char *, const char *, size_t);

					/* Wide Character Proto-Types */

extern wchar_t	*wcscat(wchar_t *, const wchar_t *);
extern wchar_t	*wcsncat(wchar_t *, const wchar_t *, size_t);
extern wchar_t	*wcscpy(wchar_t *, const wchar_t *);
extern wchar_t	*wcsncpy(wchar_t *, const wchar_t *, size_t);
extern wchar_t	*wcschr(const wchar_t *, wchar_t);
extern wchar_t	*wcsrchr(const wchar_t *, wchar_t);
extern wchar_t	*wcspbrk(const wchar_t *, const wchar_t *);
extern wchar_t	*wcstok(wchar_t *, const wchar_t *);

extern size_t	wcslen(wchar_t *);
extern int	wcscmp(const wchar_t *, const wchar_t *);
extern int	wcsncmp(const wchar_t *, const wchar_t *, size_t);
extern size_t	wcsspn(const wchar_t *, const wchar_t *);
extern size_t	wcscspn(const wchar_t *, const wchar_t *);

#endif					/************************** lint */

#ifndef	MB_CUR_MAX
#define MB_CUR_MAX	(_mb_in_tbl->th_mb_cur_max)
#endif

#endif /* _h_MBCS */
#ifdef __cplusplus
}
#endif
