367 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
| /* Test conversions */
 | |
| 
 | |
| #include "test.h"
 | |
| #include <stdlib.h>
 | |
| #include <errno.h>
 | |
| 
 | |
| static char buffer[500];
 | |
| 
 | |
| extern double_type doubles[];
 | |
| 
 | |
| /* TEST ATOF  ATOFF */
 | |
| 
 | |
| double_type *pd = doubles;
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_strtod)
 | |
| {
 | |
|   char *tail;
 | |
|   double v;
 | |
|   /* On average we'll loose 1/2 a bit, so the test is for within 1 bit  */
 | |
|   v = strtod(pd->string, &tail);
 | |
|   test_mok(v, pd->value, 64);
 | |
|   test_iok(tail - pd->string, pd->endscan);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_strtof)
 | |
| {
 | |
|   char *tail;
 | |
|   double v;
 | |
|   /* On average we'll loose 1/2 a bit, so the test is for within 1 bit  */
 | |
|   v = strtof(pd->string, &tail);
 | |
|   test_mok(v, pd->value, 32);
 | |
|   test_iok(tail - pd->string, pd->endscan);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_atof)
 | |
| {
 | |
|   test_mok(atof(pd->string), pd->value, 64);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_atoff)
 | |
| {
 | |
|   test_mok(atoff(pd->string), pd->value, 32);
 | |
| }
 | |
| 
 | |
| 
 | |
| static
 | |
| void 
 | |
| _DEFUN(iterate,(func, name),
 | |
|        void _EXFUN((*func),(void)) _AND
 | |
|        char *name)
 | |
| {
 | |
| 
 | |
|   newfunc(name);
 | |
|   pd = doubles;
 | |
|   while (pd->string) {
 | |
|     line(pd->line);
 | |
|     func();
 | |
|     pd++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| extern int_type ints[];
 | |
| 
 | |
| int_type *p = ints;
 | |
| 
 | |
| 
 | |
| static void
 | |
| _DEFUN(int_iterate,(func, name),
 | |
|        void (*func)() _AND
 | |
|        char *name)
 | |
| {
 | |
|   newfunc(name);
 | |
| 
 | |
|   p = ints;
 | |
|   while (p->string) {
 | |
|     line(p->line);
 | |
|     errno = 0;
 | |
|     func();
 | |
|     p++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN(test_strtol_base,(base, pi, string),
 | |
|        int base _AND
 | |
|        int_scan_type *pi _AND
 | |
|        char *string)
 | |
| {
 | |
|   long r;
 | |
|   char *ptr;
 | |
|   errno = 0;
 | |
|   r = strtol(string, &ptr, base);
 | |
|   test_iok(r, pi->value);
 | |
|   test_eok(errno, pi->errno_val);
 | |
|   test_iok(ptr - string, pi->end);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_strtol)
 | |
| {
 | |
|   test_strtol_base(8,&(p->octal), p->string);
 | |
|   test_strtol_base(10,&(p->decimal), p->string);
 | |
|   test_strtol_base(16, &(p->hex), p->string);
 | |
|   test_strtol_base(0, &(p->normal), p->string);
 | |
|   test_strtol_base(26, &(p->alphabetical), p->string);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_atoi)
 | |
| {
 | |
|   test_iok(atoi(p->string), p->decimal.value);
 | |
|   test_eok(errno, p->decimal.errno_val);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_atol)
 | |
| {
 | |
|   test_iok(atol(p->string), p->decimal.value);
 | |
|   test_eok(errno, p->decimal.errno_val);
 | |
| }
 | |
| 
 | |
| /* test ECVT and friends */
 | |
| extern ddouble_type ddoubles[];
 | |
| ddouble_type *pdd;
 | |
| void
 | |
| _DEFUN_VOID(test_ecvtbuf)
 | |
| {
 | |
|   int a2,a3;
 | |
|   char *s;
 | |
|   s =  ecvtbuf(pdd->value, pdd->e1, &a2, &a3, buffer);
 | |
| 
 | |
|   test_sok(s,pdd->estring);
 | |
|   test_iok(pdd->e2,a2);
 | |
|   test_iok(pdd->e3,a3);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_ecvt)
 | |
| {
 | |
|   int a2,a3;
 | |
|   char *s;
 | |
|   s =  ecvt(pdd->value, pdd->e1, &a2, &a3);
 | |
| 
 | |
|   test_sok(s,pdd->estring);
 | |
|   test_iok(pdd->e2,a2);
 | |
|   test_iok(pdd->e3,a3);
 | |
| 
 | |
|   s =  ecvtf(pdd->value, pdd->e1, &a2, &a3);
 | |
| 
 | |
|   test_sok(s,pdd->estring);
 | |
|   test_iok(pdd->e2,a2);
 | |
|   test_iok(pdd->e3,a3);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_fcvtbuf)
 | |
| {
 | |
|   int a2,a3;
 | |
|   char *s;
 | |
|   s =  fcvtbuf(pdd->value, pdd->f1, &a2, &a3, buffer);
 | |
| 
 | |
|   test_scok(s,pdd->fstring,10);
 | |
|   test_iok(pdd->f2,a2);
 | |
|   test_iok(pdd->f3,a3);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_gcvt)
 | |
| {
 | |
|   char *s = gcvt(pdd->value, pdd->g1, buffer);  
 | |
|   test_scok(s, pdd->gstring, 9);
 | |
|   
 | |
|   s = gcvtf(pdd->value, pdd->g1, buffer);  
 | |
|   test_scok(s, pdd->gstring, 9);
 | |
| 
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_fcvt)
 | |
| {
 | |
|   int a2,a3;
 | |
|   char *sd;
 | |
|   char *sf;
 | |
|   double v1;
 | |
|   double v2;
 | |
|   sd =  fcvt(pdd->value, pdd->f1, &a2, &a3);
 | |
| 
 | |
|   test_scok(sd,pdd->fstring,10);
 | |
|   test_iok(pdd->f2,a2);
 | |
|   test_iok(pdd->f3,a3);
 | |
| 
 | |
|   /* Test the float version by converting and inspecting the numbers 3
 | |
|    after reconverting */
 | |
|   sf =  fcvtf(pdd->value, pdd->f1, &a2, &a3);
 | |
|   sscanf(sd, "%lg", &v1);
 | |
|   sscanf(sf, "%lg", &v2);
 | |
|   test_mok(v1, v2,32);
 | |
|   test_iok(pdd->f2,a2);
 | |
|   test_iok(pdd->f3,a3);
 | |
| }
 | |
| 
 | |
| static void
 | |
| 
 | |
| _DEFUN(diterate,(func, name),
 | |
|        void (*func)() _AND
 | |
|        char *name)
 | |
| {
 | |
|   newfunc(name);
 | |
| 
 | |
|   pdd = ddoubles;
 | |
|   while (pdd->estring) {
 | |
|     line(pdd->line);
 | |
|     errno = 0;
 | |
|     func();
 | |
|     pdd++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(deltest)
 | |
| {
 | |
|   newfunc("rounding");
 | |
|   line(1);
 | |
|   sprintf(buffer,"%.2f", 9.999);
 | |
|   test_sok(buffer,"10.00");
 | |
|   line(2);
 | |
|   sprintf(buffer,"%.2g", 1.0);
 | |
|   test_sok(buffer,"1");
 | |
|   line(3);
 | |
|   sprintf(buffer,"%.2g", 1.2e-6);
 | |
|   test_sok(buffer,"1.2e-06");
 | |
|   line(4);
 | |
|   sprintf(buffer,"%.0g", 1.0);
 | |
|   test_sok(buffer,"1");
 | |
|   line(5);
 | |
|   sprintf(buffer,"%.0e",1e1);
 | |
|   test_sok(buffer,"1e+01");
 | |
|   line(6);  
 | |
|   sprintf(buffer, "%f", 12.3456789);
 | |
|   test_sok(buffer, "12.345679");
 | |
|   line(7);  
 | |
|   sprintf(buffer, "%6.3f", 12.3456789);
 | |
|   test_sok(buffer, "12.346");
 | |
|   line(8);  
 | |
|   sprintf(buffer,"%.0f", 12.3456789);
 | |
|   test_sok(buffer,"12");
 | |
| }
 | |
| 
 | |
| /* Most of what sprint does is tested with the tests of
 | |
|    fcvt/ecvt/gcvt, but here are some more */
 | |
| void
 | |
| _DEFUN_VOID(test_sprint)
 | |
| {
 | |
|   extern sprint_double_type sprint_doubles[];
 | |
|   sprint_double_type *s = sprint_doubles;
 | |
|   extern sprint_int_type sprint_ints[];
 | |
|   sprint_int_type *si = sprint_ints;
 | |
| 
 | |
| 
 | |
|   newfunc( "sprintf");  
 | |
| 
 | |
| 
 | |
|   while (s->line) 
 | |
|   {
 | |
|     line( s->line);
 | |
|     sprintf(buffer, s->format_string, s->value);
 | |
|     test_scok(buffer, s->result, 12); /* Only check the first 12 digs,
 | |
| 					 other stuff is random */
 | |
|     s++;
 | |
|   }
 | |
| 
 | |
|   while (si->line) 
 | |
|   {
 | |
|     line( si->line);
 | |
|     sprintf(buffer, si->format_string, si->value);
 | |
|     test_sok(buffer, si->result);
 | |
|     si++;
 | |
|   }  
 | |
| }
 | |
| 
 | |
| /* Scanf calls strtod etc tested elsewhere, but also has some pattern matching skills */
 | |
| void
 | |
| _DEFUN_VOID(test_scan)
 | |
| {
 | |
|   int i,j;
 | |
|   extern sprint_double_type sprint_doubles[];
 | |
|   sprint_double_type *s = sprint_doubles;
 | |
|   extern sprint_int_type sprint_ints[];
 | |
|   sprint_int_type *si = sprint_ints;
 | |
| 
 | |
|   newfunc( "scanf");  
 | |
|   
 | |
|   /* Test scanf by converting all the numbers in the sprint vectors
 | |
|      to and from their source and making sure nothing breaks */
 | |
| 
 | |
|   while (s->line) 
 | |
|   {
 | |
| 
 | |
|     double d0,d1;
 | |
|     line( s->line);
 | |
|     sscanf(s->result, "%lg", &d0);
 | |
|     sprintf(buffer, "%20.17e", d0);
 | |
|     sscanf(buffer, "%lg", &d1);
 | |
|     test_mok(d0,d1, 64);
 | |
|     s++;
 | |
|   }
 | |
| 
 | |
|   /* And integers too */
 | |
|   while (si->line) 
 | |
|   {
 | |
| 
 | |
|     long d0,d1;
 | |
|     
 | |
|     line(si->line);
 | |
|     sscanf(si->result, "%d", &d0);
 | |
|     sprintf(buffer, "%d", d0);
 | |
|     sscanf(buffer, "%d", &d1);
 | |
|     test_iok(d0,d1);
 | |
|     si++;
 | |
|   }
 | |
| 
 | |
|   /* And the string matching */
 | |
| 
 | |
|   sscanf("    9","%d", &i);
 | |
|   test_iok(i, 9);
 | |
|   sscanf("foo bar 123 zap 456","foo bar %d zap %d", &i, &j);
 | |
|   test_iok(i, 123);
 | |
|   test_iok(j, 456);
 | |
|   
 | |
|   sscanf("magicXYZZYfoobar","magic%[XYZ]", buffer);
 | |
|   test_sok("XYZZY", buffer);
 | |
|   sscanf("magicXYZZYfoobar","%[^XYZ]", buffer);
 | |
|   test_sok("magic", buffer);
 | |
| }
 | |
| 
 | |
| void
 | |
| _DEFUN_VOID(test_cvt)
 | |
| {
 | |
|   deltest();
 | |
| 
 | |
|   diterate(test_fcvtbuf,"fcvtbuf");
 | |
|   diterate(test_fcvt,"fcvt/fcvtf");
 | |
| 
 | |
|   diterate(test_gcvt,"gcvt/gcvtf");
 | |
|   diterate(test_ecvtbuf,"ecvtbuf");
 | |
|   diterate(test_ecvt,"ecvt/ecvtf");
 | |
|   
 | |
|   iterate(test_strtod, "strtod");
 | |
| 
 | |
|   test_scan();
 | |
|   test_sprint();  
 | |
|   iterate(test_atof, "atof");
 | |
|   iterate(test_atoff, "atoff");
 | |
| 
 | |
|   iterate(test_strtof, "strtof");
 | |
| 
 | |
|   int_iterate(test_atoi,"atoi");
 | |
|   int_iterate(test_atol,"atol");
 | |
|   int_iterate(test_strtol, "strtol");
 | |
| }
 |