diff options
Diffstat (limited to 'newlib/libm/test/convert.c')
-rw-r--r-- | newlib/libm/test/convert.c | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/newlib/libm/test/convert.c b/newlib/libm/test/convert.c new file mode 100644 index 0000000..51bddfd --- /dev/null +++ b/newlib/libm/test/convert.c @@ -0,0 +1,366 @@ +/* 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"); +} |