view CbC-examples/return_check/variable_return_type.c @ 42:9e4f9e20b8f1

add some examples.
author kent@teto.cr.ie.u-ryukyu.ac.jp
date Mon, 25 Jan 2010 17:13:59 +0900
parents
children
line wrap: on
line source

#include<stdio.h>
#include<assert.h>

#define dprint(f, args...) \
	fprintf(stdout, "in %s\t: "f, __FUNCTION__, ## args)


/* for integer.  */
int goodint = 33;
int badint = 0;
typedef void (*RETINT_FUNC)(int, void *);
void g_int(RETINT_FUNC func)
{
	func(goodint, NULL);
}
int f_int()
{
	void *ret;

	ret = _CbC_return;

	dprint("fp = %p\n", __builtin_frame_address(0));
	dprint("__return_func = %p\n", ret);
	g_int(ret);
	//goto g(ret);

	dprint("not good\n");
	return badint;
}


/* for double.  */
double gooddouble = 333.3;
double baddouble  = 0.00;
typedef void (*RETDOUBLE_FUNC)(double, void *);
void g_double(RETDOUBLE_FUNC func)
{
	func(gooddouble, NULL);
}
double f_double()
{
	void *ret;
	ret = _CbC_return;

	dprint("fp = %p\n", __builtin_frame_address(0));
	dprint("__return_func = %p\n", ret);
	g_double(ret);
	//goto g_double(ret);

	dprint("not good\n");
	return baddouble;
}

/* for float.  */
float goodfloat = 33.3f;
float badfloat = 0.0f;
typedef void (*RETFLOAT_FUNC)(float, void *);
void g_float(RETFLOAT_FUNC func)
{
	func(goodfloat, NULL);
}
float f_float()
{
	void *ret;
	ret = _CbC_return;

	dprint("fp = %p\n", __builtin_frame_address(0));
	dprint("__return_func = %p\n", ret);
	g_float(ret);
	//goto g_float(ret);

	dprint("not good\n");
	return badfloat;
}

/* for char.  */
char goodchar = 33;
char badchar  = 0;
typedef void (*RETCHAR_FUNC)(char, void *);
void g_char(RETCHAR_FUNC func)
{
	func(goodchar, NULL);
}
char f_char()
{
	void *ret;

	ret = _CbC_return;

	dprint("fp = %p\n", __builtin_frame_address(0));
	dprint("__return_func = %p\n", ret);
	g_char(ret);
	//goto g(ret);

	dprint("not good\n");
	return badchar;
}


/* for struct.  */
struct ifid {
	int a;
	float b;
	int c[4];
	double d;
};
struct ifid goodstruct = {33, 33.3, {4,4,4,4}, 333.333};
struct ifid badstruct  = {0, 00.0, {0,0,0,0}, 0.0};
typedef void (*RETSTRUCT_FUNC)(struct ifid, void *);
void g_struct(RETSTRUCT_FUNC func)
{
	func(goodstruct, NULL);
}
struct ifid f_struct()
{
	void *ret;

	ret = _CbC_return;

	dprint("fp = %p\n", __builtin_frame_address(0));
	dprint("__return_func = %p\n", ret);
	g_struct(ret);
	//goto g(ret);

	dprint("not good\n");
	return badstruct;
}

int main(int argc, char **argv)
{
	void *bptr;
	int rint;
	float rfloat;
	double rdouble;
	char rchar;
	struct ifid rstruct;

	bptr = __builtin_frame_address(0);

	dprint("before int: fp = %p\n", __builtin_frame_address(0));
	rint = f_int();
	dprint("f_int = %d,  good=%d,bad=%d\n", rint,goodint,badint);

	dprint("before float: fp = %p\n", __builtin_frame_address(0));
	rfloat = f_float();
	dprint("f_float = %3.3f, good=%3.3f,bad=%3.3f\n", rfloat,goodfloat,badfloat);
	assert(bptr==__builtin_frame_address(0));

	dprint("before double: fp = %p\n", __builtin_frame_address(0));
	rdouble = f_double();
	dprint("f_double = %3.3lf, good=%3.3lf,bad=%3.3lf\n", rdouble,gooddouble,baddouble);
	assert(bptr==__builtin_frame_address(0));

	dprint("before char: fp = %p\n", __builtin_frame_address(0));
	rchar = f_char();
	dprint("f_char = %d,  good=%d,bad=%d\n", rchar,goodchar,badchar);
	assert(bptr==__builtin_frame_address(0));

	dprint("before struct: fp = %p\n", __builtin_frame_address(0));
	rstruct = f_struct();
	dprint( "return value = {\n"
			"	a = %d\n"
			"	b = %2.3f\n"
			"	c = { %d, %d, %d, %d }\n"
			"	d = %3.3f\n"
			"}\n", rstruct.a, rstruct.b,
			rstruct.c[0],rstruct.c[1],rstruct.c[2],rstruct.c[3], rstruct.d);



	dprint("end: fp = %p\n", __builtin_frame_address(0));

	if (bptr!=__builtin_frame_address(0)) {
		dprint("CbC_return failure!\n");
		return 1;
	}
	if ( rint!=goodint 
		|| rchar!=goodchar
		|| (rfloat < goodfloat-0.01 || goodfloat+0.01 < rfloat)
		|| (rdouble < gooddouble-0.01 || gooddouble+0.01 < rdouble)
		|| rstruct.a!=goodstruct.a
		|| (rstruct.b < goodstruct.b-0.01 || goodstruct.b+0.01 < rstruct.b)
		|| (rstruct.d < goodstruct.d-0.01 || goodstruct.d+0.01 < rstruct.d)
		|| rstruct.c[0]!=goodstruct.c[0]
		|| rstruct.c[1]!=goodstruct.c[1]
		|| rstruct.c[2]!=goodstruct.c[2]
		|| rstruct.c[3]!=goodstruct.c[3] ) {
		dprint("CbC_return failure!\n");
		return 1;
	}


	dprint("CbC_return successful!\n");
	return 0;
}