/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss or reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#ifndef _BLC_STDIO_H
#define	_BLC_STDIO_H

#define	BLC_CTYPE_INLINE

#include <stddef.h>
#include <stdio_format.h>
#include <wchar.h>
#include <stdarg.h>
#include <blc_stdlib.h>
#include <ctype.h>

#define	BSIZE		24					// Size of the print buffer

/*
*	Format flags
*/

#define	FLAG_ALTF	0x01				// Alternative form flag
#define	FLAG_ZERO	0x02				// Zero padding flag
#define	FLAG_LEFT	0x04				// Left alignment flag
#define	FLAG_PLUS	0x08				// Use '+' signum flag
#define	FLAG_BLNK	0x10				// Use ' ' for positive signum flag

/*
*	Size modifiers
*/

#define	SIZE_NONE	0					// No size modifier was specified
#define	SIZE_CHAR	1					// Character (hh) size modifier
#define	SIZE_HALF	2					// Short (h) size modifier
#define	SIZE_LONG	3					// Long (l) size modifier
#define	SIZE_HUGE	4					// Long long (ll) size modifier
#define	SIZE_LDBL	5					// Long double (L) size modifier

#define	TRUE		1
#define	FALSE		0

/*
*	Types used by print_xxx()
*/

typedef struct s_printf *PRINTFP;
typedef	int (*CFUNC)( PRINTFP stat, int n );
typedef int (*WTOMF)(char*,wchar_t**);

/*
*	Structure storing the internal state for print_xxx()
*/

typedef struct s_printf {

	va_list			args;				// Argument list.
	const char		*form;				// Pointer to the format string
	size_t			maxl;				// Max characters to output
	int				nout;				// Characters written
	BLC_FMT_PUT		outf;				// Output function
	void			**outp;				// Output function parameter
	int				prec;				// Precision
	int				fldw;				// Field width
	char			flag;				// Conversion control flags
	char			size;				// Conversion size modifier
	CFUNC			cchr;				// Char and string conversion
	CFUNC			cflt;				// Float conversion
	WTOMF			wtom;				// Multibyte conversion function
	char			buff[ BSIZE ];		// Conversion buffer

} PRINTF;

/*
*	Library internal functions used by print_xxx()
*/

int		_blc_print( PRINTF *stat );
int		_blc_print_spc( PRINTF *stat, int len );
int		_blc_print_zro( PRINTF *stat, int len );
int		_blc_print_out( PRINTF *stat, const char *str, int len );
int		_blc_print_str( PRINTF *stat, int conv );

/*
*	TYpes used by scan_xxx()
*/

#define	INDX( x )	((x)>>5)
#define	BPOS( x )	(1<<((x)&31))

typedef struct s_scanf *SCANFP;
typedef	int (*SFUNC)(SCANFP);
typedef	int	(*MTOWF)(wchar_t**,const char*,size_t);

/*
*	Structure to hold the state during scan_xxx()
*/

typedef struct s_scanf {

	unsigned char	*form;				// Format string
	va_list			args;				// Argument list
	SFUNC			real;				// Float conversion function
	SFUNC			chrs;				// Character/string conversion function
	MTOWF			mtow;				// Multibyte to wide char conversion
	BLC_FMT_GET		fget;				// Get the next input char
	BLC_FMT_UNG		fung;				// Push back a char to the input
	void			**parm;				// Parameter for get/unget
	int				cbuf;				// One character buffer
	int				conv;				// Number of successful conversion
	unsigned int	cons;				// Number of characters consumed
	int				fldw;				// Field width
	unsigned char	supp;				// Suppression flag
	unsigned char	size;				// Argument size modifier
	unsigned char	type;				// Conversion type code

} SCANF;

/*
*	Library internal functions for scan_xxx()
*/

int		_blc_scan( SCANF *stat );
int		_blc_scan_get( SCANF *stat );
void	_blc_scan_ung( SCANF *stat, int c );
int		_blc_scan_digits( SCANF *stat, BLC_S2I *conv );
int		_blc_scan_space( SCANF *stat );
int		_blc_scan_chars( SCANF *stat );
int		_blc_scan_cset( SCANF *stat, unsigned *cset );

#endif

