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_strtodf)
|
||
|
{
|
||
|
char *tail;
|
||
|
double v;
|
||
|
/* On average we'll loose 1/2 a bit, so the test is for within 1 bit */
|
||
|
v = strtodf(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_strtodf, "strtodf");
|
||
|
|
||
|
int_iterate(test_atoi,"atoi");
|
||
|
int_iterate(test_atol,"atol");
|
||
|
int_iterate(test_strtol, "strtol");
|
||
|
}
|