/* func_pointers.c - examples of parameterization of operations using ptrs */

/* bases.c : print addition/multiplication for base 8, 10, 16 */

#include <stdio.h>
#include <string.h>

void PutcharN(char ch, int n)
{
	while(n--)
		putchar(ch);
	return;
}

int Add(int a, int b)
{
	return a + b;
}

int Mult(int a, int b)
{
	return a * b;
}

void Chart(int min, int max, int (*function)(int, int),
		   int width, const char form_char,
		   const char *title)
{
	int x, y;
	char num_fmt[] = { '%', '4', 'd', '\0' }; /* example */
	int chart_inner_width = (max - min + 1) * (width + 1);
	const char *digits = "0123456789";
	
	num_fmt[1] = width < 10 ? digits[width] : 10 ;
	num_fmt[2] = form_char;

	putchar('\n');									/* header */
	PutcharN(' ', (2 * width + 4 + chart_inner_width - strlen(title)) / 2);
	fputs(title, stdout);
	putchar('\n');

	PutcharN(' ', 1 + width);
	putchar(' ');									/* numbers across */
	for(y = min ; y <= max ; ++y)
	{
		printf(&num_fmt[0], y);		
		putchar(' ');
	}
	putchar(' ');
	putchar('\n');

	PutcharN(' ', 1 + width);
	putchar('+');									/* +---...----+ */
	PutcharN('-', chart_inner_width);
	putchar('+');
	putchar('\n');
	
	for(y = min ; y <= max ; ++y)
	{
		printf(&num_fmt[0], y);
		fputs(" |", stdout);
		for(x = min ; x <= max ; ++x)
		{
			int result = (*function)(x, y);
			printf(&num_fmt[0], result);
			putchar(' ');
		}
		fputs("| ", stdout);
		printf(&num_fmt[0], y);
		putchar('\n');
	}

	PutcharN(' ', 1 + width);
	putchar('+');									/* +---...----+ */
	PutcharN('-', chart_inner_width);
	putchar('+');
	putchar('\n');

	PutcharN(' ', 1 + width);
	putchar(' ');									/* numbers across */
	for(y = min ; y <= max ; ++y)
	{
		printf(&num_fmt[0], y);		
		putchar(' ');
	}
	putchar(' ');
	putchar('\n');

	return;
}

int main()
{
	Chart(0,  010, Add,  3, 'o', "Octal Addition");
	Chart(0,  010, Mult, 3, 'o', "Octal Multiplication");	
	Chart(0,   10, Add,  3, 'd', "Decimal Addition");
	Chart(0,   10, Mult, 3, 'd', "Decimal Multiplication");	
	Chart(0, 0x10, Add,  3, 'x', "Hex Addition");
	Chart(0, 0x10, Mult, 3, 'x', "Hex Multiplication");	
	return 0;
}



