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");
 | 
						|
}
 |