/*	Comprehensive RPC system test:	Calling program - C Version
	============================= 

	21 Apr 87	Bug out: test sequence was not initialised.
	31 Aug 87	C version derived - Nici.
	27 Nov 89	Explicit initialisation put in - TBL
*/

#include <stdio.h>
#include <rpcrts.h>

#define	byte_type   rpc_byte
#define	char_type   rpc_char
#define	short_type  rpc_short
#define	long_type   rpc_long
#define	real_type   rpc_real32
typedef rpc_char    str_type[81];
typedef rpc_char    substr_type[80];
typedef rpc_char    array_type[11][8];
typedef	rpc_integer seq_type[80];

byte_type  my_byte,  his_byte;
char_type  my_char,  his_char;
short_type my_short, his_short;
long_type  my_long,  his_long;
real_type  my_real,  his_real;
str_type   my_str,   his_str;
array_type my_array, his_array;

substr_type a_my_substr, a_his_substr;
rpc_integer s_my_substr, s_his_substr,
	    l_my_substr, l_his_substr;

seq_type    a_my_seq, a_his_seq;
rpc_integer l_my_seq, l_his_seq;

int i, j;		/* loop counters */
int errors = 0;		/* global error count */

#include "big.ext"

static strncmp(a, b, n)	/* compares a and b for up to n characters */

char *a, *b;
int n;
{	for (i = 0; i < n && a[i] == b[i]; i++);
	return(a[i] - b[i]);
	}

check()		/* check the two sets are the same */

{	if (his_byte != my_byte)
            printf("Error %d: bad byte %d -> %d\n", ++errors, (int)my_byte, (int)his_byte);
		
	if (his_char != my_char)
            printf("Error %d: bad char %c -> %c\n", ++errors, my_char, his_char);

	if (his_short != my_short)
            printf("Error %d: bad short %d -> %d\n", ++errors, my_short, his_short);

	if (his_long != my_long)
            printf("Error %d: bad long %lx -> %lx\n", ++errors, my_long, his_long);

	if (his_real != my_real)
            printf("Error %d: bad real %f (%lx) -> %f (%lx)\n",
		     ++errors, my_real, *(long *)&my_real, his_real,
						 *(long *)&his_real);

	if (strncmp(his_str, my_str, 80))
            printf("Error %d: bad string\n%s\n  ->\n%s\n",
		     ++errors, my_str, his_str);

	if (s_his_substr != s_my_substr)
            printf("Error %d: bad substring start %d -> %d\n",
		     ++errors, s_my_substr, s_his_substr);

	if (l_his_substr != l_my_substr)
            printf("Error %d: bad substring length %d -> %d\n",
		     ++errors, l_my_substr, l_his_substr);

	for (i=s_his_substr; i < s_his_substr+l_his_substr; i++)
	    if (a_my_substr[i-1] != a_his_substr[i-1])
		printf(
		"Error %d: Substring character `%c' (%x) should be `%c' (%x)\n",
			++errors, a_his_substr[i-1], a_his_substr[i-1],
			a_my_substr[i-1], a_my_substr[i-1]);

	for (i = 0; i < 11; i++) 
	    for (j = 0; j < 8; j++)
		if (his_array[i][j] != my_array[i][j])
                    printf("Error %d: bad array element [%d][%d] %c -> %c\n", ++errors, i, j, my_array[i][j], his_array[i][j]);

	if (l_his_seq != l_my_seq)
            printf("Error %d: bad sequence length %d -> %d\n", ++errors, l_my_seq, l_his_seq);

	for (i = 0; i < l_my_seq; i++) 
	    if (a_his_seq[i] != a_my_seq[i])
                printf("Error %d: bad sequence element [%d] %lx -> %lx\n", ++errors, i, a_my_seq[i], a_his_seq[i]);
        }

static char *init_str =
"The quick brown fox jumps over the lazy dog ^%@!()[]{} 3.14159265356979323846 &;:...";
 
set_my_data()	/* set up a test data set */

{

	my_byte = 77;
	my_char = '#';
	my_short = 12345;
	my_long = -1001;
	my_real = 3.1415926;

	strncpy(my_str, init_str, 80);
	strncpy(a_my_substr, init_str, 80);
	
	for (i = 0; i < 80; i++)
	{   a_my_seq[i] = (i+1)*(i+1)*(i+1);
	    }
	my_str[80] = '\0';	/* Terminate the string */
	s_my_substr = 11;	/* substring start PLUS ONE */
	l_my_substr = 25;	/* substring length   */
	l_my_seq = 80;

	for (i = 0; i < 11; i++)
	    for (j = 0; j < 8; j++)
		my_array[i][j] = init_str[ ((j-i) < 0 ? i-j : j-i) % 80];
	}


	/* modify the parameters in a standard way */
#include "bigmod.h"

/*
{	performance test
	----------------
}
procedure performance_test;
TYPE
	daytime		=	packed array[1..11] of char;

VAR	i, n:		integer;
	start, finish:	daytime;
	delta:		real;

   FUNCTION hundredths(t: daytime): integer;

	function digit(i: integer): integer;
	begin
		digit := ord(t[i]) - ord('0');
	end;

   BEGIN
	hundredths := digit(11) + 10 *
	  ( digit(10) + 10 *
	    ( digit(8) + 10 *
	      ( digit(7) + 6 *
		( digit(5) + 10 *
		  ( digit(4) + 6 *
		    ( digit(2) + 10 *
		      digit(1)
	  ) ) ) ) ) );
   END;

BEGIN
	n := 100;
*IF DEF VAXVMS
	time(start);
*ENDIF
	For i := 1 to n do begin
		x := 7;
		y := 11;
		z := 13;

		r := bigsub1(x, y, z);
	end;

*IF DEF VAXVMS
	time(finish);

	delta := (hundredths(finish) - hundredths(start))*10/n;

	writeln(output,	delta:5:2,' ms/transaction r:= bigsub(x,y,z)');
*ENDIF
END;
*/
extern void open_bigsub();

main()
{	int x, y, z, r;

	open_bigsub();	    /* Connect to remote module */

/*	Test a general simple routine first, to pick up silly ones:  */

	x = 7;
	y = 11;
	z = 13;

	r = bigsub1(&x, &y, &z);
	if (y !=18 || z != x*3 || r != x*x)
	{   printf("bigsub1 failed: bigsub1(%d, %d, %d) == %d\n", x, y, z, r);
            exit(2);
	    }
	else printf("passed bigsub1() call...\n");

	set_my_data();		/* set up my_xxxx */

	/* send data to the far end */
	only_in(&my_byte, &my_char, &my_short, &my_long, &my_real, my_str,
		a_my_substr, &s_my_substr, &l_my_substr, my_array,
		a_my_seq, &l_my_seq);

	/* get a copy back */
	only_out(&his_byte, &his_char, &his_short, &his_long, &his_real,
                 his_str, a_his_substr, &s_his_substr, &l_his_substr,
                 his_array, a_his_seq, &l_his_seq);

	check();	/* that the results match */

	if (errors) exit(2);	
	else printf("passed only_in() & only_out()...\n");

	/* get the copy modified */
	in_out(&his_byte, &his_char, &his_short, &his_long, &his_real, 
               his_str, a_his_substr, &s_his_substr, &l_his_substr,
               his_array, a_his_seq, &l_his_seq);

	bigmod();	/* modify my_xxxx to match */

	check();	/* that the results match */

	if (!errors) printf("passed in-modify-out test - congratulations!\n");

	}	/* main */
