/*****
 NAME
	cint-test.m 
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#include <coconut/cint.h>
#include <stdlib.h>

const char * result2str(id result)
{
	static char okstr[] = "OK" ;
	static char ngstr[] = "NG" ;
	return result == nil ? okstr : ngstr ;
}

void print_int(id <PNumber> obj1, id <PNumber> obj2)
{
	printf("obj1 = %d, obj2 = %d\n", [obj1 intNum], [obj2 intNum]) ;
}

void testBinStr(const char * bin)
{
	char 		str[66] ;
	u_int64_t	val ;
	id		result ;

	val = 1234UL ;
	printf("bin value : %s (result %llu) \n", bin, val) ;
	result = [CInt binStrToUInt64: bin to: &val] ;
	printf(" the value is %llu (result %s)\n", val, result2str(result)) ;
	result = [CInt uInt64ToBinStr: val to: str] ;
	printf(" the str is %s (result %s)\n", str, result2str(result)) ;
}

void testStrToULong(const char * str)
{
	unsigned long int	val ;
	id			result ;

	result = [CInt strToULong: str to: &val] ;
	printf("str: \"%s\" -> value: %ld (result %s)\n", str, val, 
	  result2str(result)) ;
}

int main()
{
	const char	bin1[] = "0b0" ;
	const char	bin2[] = "0b1" ;
	const char	bin3[] = "0b1111" ;
	char		bin4[65]  ;
	id <PNumber>	obj1 ;
	id <PNumber>	obj2 ;
	int 		rval, i ;

	printf("*** test program for CInt class\n") ;
	obj1 = [[CInt alloc] init] ;
	obj2 = [[CInt alloc] init] ;
	printf("initial state:\n") ;
	print_int(obj1, obj2) ;

	printf("set methods:\n") ;
	[obj1 setInt: 2] ;
	[obj2 setReal: 3.14] ;
	print_int(obj1, obj2) ;
	[obj1 setObject: obj2] ;
	print_int(obj1, obj2) ;

	printf("get methods:\n") ;
	[obj1 setInt: 123] ;
	[obj2 setObject: obj1] ;
	print_int(obj1, obj2) ;
	[obj1 setInt: 456] ;
	[obj2 setInt: [obj1 intNum]] ;
	print_int(obj1, obj2) ;
	[obj1 setInt: 789] ;
	[obj2 setReal: [obj1 realNum]] ;
	print_int(obj1, obj2) ;

	printf("add methods:\n") ;
	[obj1 setInt: 1] ;
	[obj2 setInt: 2] ;
	print_int([obj1 addObject: obj2], obj2) ;
	print_int(obj1, [obj2 addInt: [obj2 intNum]]) ;
	print_int([obj1 addReal: [obj2 realNum]], obj2) ;

	printf("random number test\n") ;
	/* In normally, this method is called in CSystem class */
	[CInt initRandomSeed] ;
	for(i=0 ; i<10 ; i++){
		rval = [CInt getRandomInt: -i to: i] ;
		if(rval < -i || i < rval){
			printf("illegal random number %d\n", rval);
			exit(1) ;
		} else {
			printf("random [%d, %d] = <can not print>\n", -i, i) ; 
		}
		/* printf("random [%d, %d] = %d\n", -i, i, rval) ; */
	}

	/* factroy methods */
	printf("*** test program for functions in fstring.c\n") ;
	testBinStr(bin1) ;
	testBinStr(bin2) ;
	testBinStr(bin3) ;

	printf("MAX_U_INT64 : %llu\n", MAX_U_INT64) ;
	for(i=0 ; i<64 ; i++) bin4[i] = '1' ; 
	bin4[64] = '\0' ;
	testBinStr(bin4) ;

	printf("strToULong factory method:\n") ;
	testStrToULong("1234") ;
	testStrToULong("1") ;
	testStrToULong("abc") ;

	printf("duplicate:\n") ;
	print_int(obj1, [obj1 duplicate]) ;

	[obj1 release] ; [obj2 release] ;
	printf("bye.\n") ;
	return 0 ;
}

