From patchwork Wed Aug 14 17:25:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 95846 X-Patchwork-Delegate: dj@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BCE5A385840A for ; Wed, 14 Aug 2024 17:25:42 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 67C463858D20 for ; Wed, 14 Aug 2024 17:25:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 67C463858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 67C463858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1723656318; cv=none; b=okFEWJoasSJcIv2lWbzdy6OJjYkQP7JrlIAepv1eSHdz3bjADbRosuaXt9oAdaDw5h/WjSyNK+9B6jM6249WRvriN1NuhsIpvTtBQjgwse+3zwodtXucqH/mzGY3GMSs0f1RxN/CY0g19qHwNZLhGwyvWB2XOU3dSUgtYdtxRb4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1723656318; c=relaxed/simple; bh=pr9bouYJ9KfVTJDrEMn1JM3VXRRZbu7SD1gdwbqmlO0=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=eJ6qcD+ui+EQ5ffXVh9v5oKDCULXf+oMCrXYMZfDUYSGF9AWwVZdXxrf221Yfy58wewohmsMwUJ7iHfnxJmnZg+SnJRDeufVkcHH8NRrcal076yWOCNP77hPzhBV/fgBej+5GGtyCktyFUWgIBF05rwJjzWE0Lrrc5xtZDz2Q6Q= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1723656316; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=ujvAAoeLdjw3kz1zEfwMbjPibq+ivFfU3ZnxfCxBhSQ=; b=QCoUBCGXw2JdvfnBcstww0jIDAqVt0orkielcFvGWQfApV1W+fxynhyRfovrwuStw7hzGw POepuK6vDqwWFVq97YWwiRp//ztC/O2SXggjyGPQSkAQLwEZOFPt/mLD3ere7Axs5S0oND LA/EvsZdKzYez+kreXrwUQvTgw1E0dc= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-342-zbywm20_P1aMUXZ0aMT4iQ-1; Wed, 14 Aug 2024 13:25:14 -0400 X-MC-Unique: zbywm20_P1aMUXZ0aMT4iQ-1 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-368448dfe12so593773f8f.1 for ; Wed, 14 Aug 2024 10:25:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723656313; x=1724261113; h=mime-version:references:message-id:in-reply-to:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ujvAAoeLdjw3kz1zEfwMbjPibq+ivFfU3ZnxfCxBhSQ=; b=W2/GSEOSgvohm+zSoksR5vT0NVGOCVd1cGrW7ysk+PFSYjcFha1fAAuG9S8bTp4l9A UOG1vqCL86MzgYDbZBKQCgSMwa0w0Z6+8j4jot1TOh+BFvR+wmYnHuspID/bTXQuKuAK mUrvVXZstB0liyDKtXAbvTyjZSgjkSoMoBPDoNb4OMEsoF4D6WYCgEZxb+3rZmKShHg5 wjDjtmrgAyylnVRIwscL5GThLwZ0cOFfr+s2RuFtsPwiNFamnFB+CjHZEI3WUrtsjL5l YIaxCqVYrd2jWsdWMZ0At/0AYmoKyER22Up3AIY35DtK8zKPEwo30pR0xMiVExtqNWtv hkuA== X-Gm-Message-State: AOJu0YzF9j3UqDtK8MoVfaiV5SklinavtxAbdwbFEIOc2ze7J7ekNlfA oMzAQdJHz4lCVVf74a6HKWmkzm5ucc6FXBC+1lJS4iCmF9qnXYf970O6HIcOApl5Mb4QRPhogfP fkBCbXu1Vy8w06E1vj7x+XM3CKDw4VgN3ySoes9Hxp5qJZbbQlic6xklkcjQmDMyQnfqNahhHAy wrrwdVNgPtqSKHn93ICTdipAeWEy3d+frxDuCONQ1T3w== X-Received: by 2002:adf:f648:0:b0:366:ee84:6a77 with SMTP id ffacd0b85a97d-37186bbd203mr361443f8f.3.1723656312984; Wed, 14 Aug 2024 10:25:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEJvr6xOka3lb/RmX8jQOnbM3IsJFqT2EBtsnjTxw4aaml0meUv7obPex2G7TeNFx0E+DoMOg== X-Received: by 2002:adf:f648:0:b0:366:ee84:6a77 with SMTP id ffacd0b85a97d-37186bbd203mr361404f8f.3.1723656312030; Wed, 14 Aug 2024 10:25:12 -0700 (PDT) Received: from digraph.polyomino.org.uk (digraph.polyomino.org.uk. [2001:8b0:bf73:93f7::51bb:e332]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-36e4ebd2bebsm13312762f8f.93.2024.08.14.10.25.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Aug 2024 10:25:11 -0700 (PDT) Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.95) (envelope-from ) id 1seHkE-00AaRK-3B for libc-alpha@sourceware.org; Wed, 14 Aug 2024 17:25:10 +0000 Date: Wed, 14 Aug 2024 17:25:10 +0000 (UTC) From: Joseph Myers To: libc-alpha@sourceware.org Subject: [PATCH v2] Make __strtod_internal tests type-generic In-Reply-To: <5574ff7-321a-1883-10c-1ed9435d7116@redhat.com> Message-ID: <16b38dae-22b-12a-62fd-6c6216bba6@redhat.com> References: <5574ff7-321a-1883-10c-1ed9435d7116@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-9.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Make __strtod_internal tests type-generic Some of the strtod tests use type-generic machinery in tst-strtod.h to test the strto* functions for all floating types, while others only test double even when the tests are in fact meaningful for all floating types. Convert the tests of the internal __strtod_internal interface to cover all floating types. I haven't tried to convert them to use newer test interfaces in other ways, just made the changes necessary to use the type-generic machinery. As an internal interface, there are no aliases for different types with the same ABI (however, __strtold_internal is defined even if long double has the same ABI as double), so macros used by the type-generic testing code are redefined as needed to avoid expecting such aliases to be present. Tested for x86_64. Reviewed-by: DJ Delorie --- Changed in v2: define _LIBC_TEST in strtod5i.c to ensure copysignl is declared on platforms where long double has the same ABI as double (as an internal test, the rules about not declaring such aliases apply by default), shown to be needed by CI on Arm. diff --git a/stdlib/tst-strtod1i.c b/stdlib/tst-strtod1i.c index 9d6bb760fb..dec1ef37c1 100644 --- a/stdlib/tst-strtod1i.c +++ b/stdlib/tst-strtod1i.c @@ -25,60 +25,91 @@ #include #include -/* Perform a few tests in a locale with thousands separators. */ -static int -do_test (void) -{ - static const struct - { - const char *loc; - const char *str; - double exp; - ptrdiff_t nread; - } tests[] = - { - { "de_DE.UTF-8", "1,5", 1.5, 3 }, - { "de_DE.UTF-8", "1.5", 1.0, 1 }, - { "de_DE.UTF-8", "1.500", 1500.0, 5 }, - { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65, 26 } - }; -#define ntests (sizeof (tests) / sizeof (tests[0])) - size_t n; - int result = 0; - - puts ("\nLocale tests"); +#include "tst-strtod.h" - for (n = 0; n < ntests; ++n) - { - double d; - char *endp; +/* This tests internal interfaces, which are only defined for types + with distinct ABIs, so diable testing for types without distinct + ABIs. */ +#undef IF_FLOAT32 +#define IF_FLOAT32(x) +#undef IF_FLOAT64 +#define IF_FLOAT64(x) +#undef IF_FLOAT32X +#define IF_FLOAT32X(x) +#undef IF_FLOAT64X +#define IF_FLOAT64X(x) +#if !__HAVE_DISTINCT_FLOAT128 +# undef IF_FLOAT128 +# define IF_FLOAT128(x) +#endif - if (setlocale (LC_ALL, tests[n].loc) == NULL) - { - printf ("cannot set locale %s\n", tests[n].loc); - result = 1; - continue; - } +#define ntests (sizeof (tests) / sizeof (tests[0])) - d = __strtod_internal (tests[n].str, &endp, 1); - if (d != tests[n].exp) - { - printf ("strtod(\"%s\") returns %g and not %g\n", - tests[n].str, d, tests[n].exp); - result = 1; - } - else if (endp - tests[n].str != tests[n].nread) - { - printf ("strtod(\"%s\") read %td bytes and not %td\n", - tests[n].str, endp - tests[n].str, tests[n].nread); - result = 1; - } - } +/* Perform a few tests in a locale with thousands separators. */ +#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ +static int \ +test_strto ## FSUF (void) \ +{ \ + static const struct \ + { \ + const char *loc; \ + const char *str; \ + FTYPE exp; \ + ptrdiff_t nread; \ + } tests[] = \ + { \ + { "de_DE.UTF-8", "1,5", 1.5 ## LSUF, 3 }, \ + { "de_DE.UTF-8", "1.5", 1.0 ## LSUF, 1 }, \ + { "de_DE.UTF-8", "1.500", 1500.0 ## LSUF, 5 }, \ + { "de_DE.UTF-8", "36.893.488.147.419.103.232", 0x1.0p65 ## LSUF, 26 } \ + }; \ + size_t n; \ + int result = 0; \ + \ + puts ("\nLocale tests"); \ + \ + for (n = 0; n < ntests; ++n) \ + { \ + FTYPE d; \ + char *endp; \ + \ + if (setlocale (LC_ALL, tests[n].loc) == NULL) \ + { \ + printf ("cannot set locale %s\n", tests[n].loc); \ + result = 1; \ + continue; \ + } \ + \ + d = __strto ## FSUF ## _internal (tests[n].str, &endp, 1); \ + if (d != tests[n].exp) \ + { \ + char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ + FTOSTR (buf1, sizeof (buf1), "%g", d); \ + FTOSTR (buf2, sizeof (buf2), "%g", tests[n].exp); \ + printf ("strto" # FSUF "(\"%s\") returns %s and not %s\n", \ + tests[n].str, buf1, buf2); \ + result = 1; \ + } \ + else if (endp - tests[n].str != tests[n].nread) \ + { \ + printf ("strto" # FSUF "(\"%s\") read %td bytes and not %td\n", \ + tests[n].str, endp - tests[n].str, tests[n].nread); \ + result = 1; \ + } \ + } \ + \ + if (result == 0) \ + puts ("all OK"); \ + \ + return result ? EXIT_FAILURE : EXIT_SUCCESS; \ +} - if (result == 0) - puts ("all OK"); +GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) - return result ? EXIT_FAILURE : EXIT_SUCCESS; +static int +do_test (void) +{ + return STRTOD_TEST_FOREACH (test_strto); } #include diff --git a/stdlib/tst-strtod3.c b/stdlib/tst-strtod3.c index 23abec1896..fc4efd44d1 100644 --- a/stdlib/tst-strtod3.c +++ b/stdlib/tst-strtod3.c @@ -3,19 +3,73 @@ #include #include -static const struct -{ - const char *in; - const char *out; - double expected; -} tests[] = - { - { "000,,,e1", ",,,e1", 0.0 }, - { "000e1", "", 0.0 }, - { "000,1e1", ",1e1", 0.0 } - }; -#define NTESTS (sizeof (tests) / sizeof (tests[0])) +#include "tst-strtod.h" + +/* This tests internal interfaces, which are only defined for types + with distinct ABIs, so diable testing for types without distinct + ABIs. */ +#undef IF_FLOAT32 +#define IF_FLOAT32(x) +#undef IF_FLOAT64 +#define IF_FLOAT64(x) +#undef IF_FLOAT32X +#define IF_FLOAT32X(x) +#undef IF_FLOAT64X +#define IF_FLOAT64X(x) +#if !__HAVE_DISTINCT_FLOAT128 +# undef IF_FLOAT128 +# define IF_FLOAT128(x) +#endif +#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ +static const struct \ +{ \ + const char *in; \ + const char *out; \ + FTYPE expected; \ +} tests_strto ## FSUF[] = \ + { \ + { "000,,,e1", ",,,e1", 0.0 ## LSUF }, \ + { "000e1", "", 0.0 ## LSUF }, \ + { "000,1e1", ",1e1", 0.0 ## LSUF } \ + }; \ + \ +static int \ +test_strto ## FSUF (void) \ +{ \ + int status = 0; \ + \ + for (int i = 0; \ + i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ + ++i) \ + { \ + char *ep; \ + FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ + &ep, 1); \ + \ + if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \ + { \ + printf ("%d: got rest string \"%s\", expected \"%s\"\n", \ + i, ep, tests_strto ## FSUF[i].out); \ + status = 1; \ + } \ + \ + if (r != tests_strto ## FSUF[i].expected) \ + { \ + char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ + FTOSTR (buf1, sizeof (buf1), "%g", r); \ + FTOSTR (buf2, sizeof (buf2), "%g", \ + tests_strto ## FSUF[i].expected); \ + printf ("%d: got wrong results %s, expected %s\n", \ + i, buf1, buf2); \ + status = 1; \ + } \ + } \ + \ + return status; \ +} + +GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) static int do_test (void) @@ -26,29 +80,7 @@ do_test (void) return 1; } - int status = 0; - - for (int i = 0; i < NTESTS; ++i) - { - char *ep; - double r = __strtod_internal (tests[i].in, &ep, 1); - - if (strcmp (ep, tests[i].out) != 0) - { - printf ("%d: got rest string \"%s\", expected \"%s\"\n", - i, ep, tests[i].out); - status = 1; - } - - if (r != tests[i].expected) - { - printf ("%d: got wrong results %g, expected %g\n", - i, r, tests[i].expected); - status = 1; - } - } - - return status; + return STRTOD_TEST_FOREACH (test_strto); } #define TEST_FUNCTION do_test () diff --git a/stdlib/tst-strtod4.c b/stdlib/tst-strtod4.c index 6cc4e843c7..d4e569e8fc 100644 --- a/stdlib/tst-strtod4.c +++ b/stdlib/tst-strtod4.c @@ -3,22 +3,76 @@ #include #include +#include "tst-strtod.h" + +/* This tests internal interfaces, which are only defined for types + with distinct ABIs, so diable testing for types without distinct + ABIs. */ +#undef IF_FLOAT32 +#define IF_FLOAT32(x) +#undef IF_FLOAT64 +#define IF_FLOAT64(x) +#undef IF_FLOAT32X +#define IF_FLOAT32X(x) +#undef IF_FLOAT64X +#define IF_FLOAT64X(x) +#if !__HAVE_DISTINCT_FLOAT128 +# undef IF_FLOAT128 +# define IF_FLOAT128(x) +#endif + #define NNBSP "\xe2\x80\xaf" -static const struct -{ - const char *in; - const char *out; - double expected; -} tests[] = - { - { "000"NNBSP"000"NNBSP"000", "", 0.0 }, - { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 }, - /* Bug 30964 */ - { "10"NNBSP NNBSP"200", NNBSP NNBSP"200", 10.0 } - }; -#define NTESTS (sizeof (tests) / sizeof (tests[0])) +#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ +static const struct \ +{ \ + const char *in; \ + const char *out; \ + FTYPE expected; \ +} tests_strto ## FSUF[] = \ + { \ + { "000"NNBSP"000"NNBSP"000", "", 0.0 ## LSUF }, \ + { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 ## LSUF }, \ + /* Bug 30964 */ \ + { "10"NNBSP NNBSP"200", NNBSP NNBSP"200", 10.0 ## LSUF } \ + }; \ + \ +static int \ +test_strto ## FSUF (void) \ +{ \ + int status = 0; \ + \ + for (int i = 0; \ + i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ + ++i) \ + { \ + char *ep; \ + FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ + &ep, 1); \ + \ + if (strcmp (ep, tests_strto ## FSUF[i].out) != 0) \ + { \ + printf ("%d: got rest string \"%s\", expected \"%s\"\n", \ + i, ep, tests_strto ## FSUF[i].out); \ + status = 1; \ + } \ + \ + if (r != tests_strto ## FSUF[i].expected) \ + { \ + char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ + FTOSTR (buf1, sizeof (buf1), "%g", r); \ + FTOSTR (buf2, sizeof (buf2), "%g", \ + tests_strto ## FSUF[i].expected); \ + printf ("%d: got wrong results %s, expected %s\n", \ + i, buf1, buf2); \ + status = 1; \ + } \ + } \ + \ + return status; \ +} +GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) static int do_test (void) @@ -29,29 +83,7 @@ do_test (void) return 1; } - int status = 0; - - for (int i = 0; i < NTESTS; ++i) - { - char *ep; - double r = __strtod_internal (tests[i].in, &ep, 1); - - if (strcmp (ep, tests[i].out) != 0) - { - printf ("%d: got rest string \"%s\", expected \"%s\"\n", - i, ep, tests[i].out); - status = 1; - } - - if (r != tests[i].expected) - { - printf ("%d: got wrong results %g, expected %g\n", - i, r, tests[i].expected); - status = 1; - } - } - - return status; + return STRTOD_TEST_FOREACH (test_strto); } #define TEST_FUNCTION do_test () diff --git a/stdlib/tst-strtod5i.c b/stdlib/tst-strtod5i.c index ee54e3404c..aaae486884 100644 --- a/stdlib/tst-strtod5i.c +++ b/stdlib/tst-strtod5i.c @@ -16,52 +16,112 @@ License along with the GNU C Library; if not, see . */ +/* Defining _LIBC_TEST ensures long double math functions are + declared in the headers. */ +#define _LIBC_TEST 1 #include #include #include #include #include +#include "tst-strtod.h" + +/* This tests internal interfaces, which are only defined for types + with distinct ABIs, so diable testing for types without distinct + ABIs. */ +#undef IF_FLOAT32 +#define IF_FLOAT32(x) +#undef IF_FLOAT64 +#define IF_FLOAT64(x) +#undef IF_FLOAT32X +#define IF_FLOAT32X(x) +#undef IF_FLOAT64X +#define IF_FLOAT64X(x) +#if !__HAVE_DISTINCT_FLOAT128 +# undef IF_FLOAT128 +# define IF_FLOAT128(x) +#endif + #define NNBSP "\xe2\x80\xaf" -static const struct -{ - const char *in; - int group; - double expected; -} tests[] = - { - { "0", 0, 0.0 }, - { "000", 0, 0.0 }, - { "-0", 0, -0.0 }, - { "-000", 0, -0.0 }, - { "0,", 0, 0.0 }, - { "-0,", 0, -0.0 }, - { "0,0", 0, 0.0 }, - { "-0,0", 0, -0.0 }, - { "0e-10", 0, 0.0 }, - { "-0e-10", 0, -0.0 }, - { "0,e-10", 0, 0.0 }, - { "-0,e-10", 0, -0.0 }, - { "0,0e-10", 0, 0.0 }, - { "-0,0e-10", 0, -0.0 }, - { "0e-1000000", 0, 0.0 }, - { "-0e-1000000", 0, -0.0 }, - { "0,0e-1000000", 0, 0.0 }, - { "-0,0e-1000000", 0, -0.0 }, - { "0", 1, 0.0 }, - { "000", 1, 0.0 }, - { "-0", 1, -0.0 }, - { "-000", 1, -0.0 }, - { "0e-10", 1, 0.0 }, - { "-0e-10", 1, -0.0 }, - { "0e-1000000", 1, 0.0 }, - { "-0e-1000000", 1, -0.0 }, - { "000"NNBSP"000"NNBSP"000", 1, 0.0 }, - { "-000"NNBSP"000"NNBSP"000", 1, -0.0 } - }; -#define NTESTS (sizeof (tests) / sizeof (tests[0])) +#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ +static const struct \ +{ \ + const char *in; \ + int group; \ + FTYPE expected; \ +} tests_strto ## FSUF[] = \ + { \ + { "0", 0, 0.0 ## LSUF }, \ + { "000", 0, 0.0 ## LSUF }, \ + { "-0", 0, -0.0 ## LSUF }, \ + { "-000", 0, -0.0 ## LSUF }, \ + { "0,", 0, 0.0 ## LSUF }, \ + { "-0,", 0, -0.0 ## LSUF }, \ + { "0,0", 0, 0.0 ## LSUF }, \ + { "-0,0", 0, -0.0 ## LSUF }, \ + { "0e-10", 0, 0.0 ## LSUF }, \ + { "-0e-10", 0, -0.0 ## LSUF }, \ + { "0,e-10", 0, 0.0 ## LSUF }, \ + { "-0,e-10", 0, -0.0 ## LSUF }, \ + { "0,0e-10", 0, 0.0 ## LSUF }, \ + { "-0,0e-10", 0, -0.0 ## LSUF }, \ + { "0e-1000000", 0, 0.0 ## LSUF }, \ + { "-0e-1000000", 0, -0.0 ## LSUF }, \ + { "0,0e-1000000", 0, 0.0 ## LSUF }, \ + { "-0,0e-1000000", 0, -0.0 ## LSUF }, \ + { "0", 1, 0.0 ## LSUF }, \ + { "000", 1, 0.0 ## LSUF }, \ + { "-0", 1, -0.0 ## LSUF }, \ + { "-000", 1, -0.0 ## LSUF }, \ + { "0e-10", 1, 0.0 ## LSUF }, \ + { "-0e-10", 1, -0.0 ## LSUF }, \ + { "0e-1000000", 1, 0.0 ## LSUF }, \ + { "-0e-1000000", 1, -0.0 ## LSUF }, \ + { "000"NNBSP"000"NNBSP"000", 1, 0.0 ## LSUF }, \ + { "-000"NNBSP"000"NNBSP"000", 1, -0.0 ## LSUF } \ + }; \ + \ +static int \ +test_strto ## FSUF (void) \ +{ \ + int status = 0; \ + \ + for (int i = 0; \ + i < sizeof (tests_strto ## FSUF) / sizeof (tests_strto ## FSUF[0]); \ + ++i) \ + { \ + char *ep; \ + FTYPE r = __strto ## FSUF ## _internal (tests_strto ## FSUF[i].in, \ + &ep, \ + tests_strto ## FSUF[i].group); \ + \ + if (*ep != '\0') \ + { \ + printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); \ + status = 1; \ + } \ + \ + if (r != tests_strto ## FSUF[i].expected \ + || (copysign ## CSUF (10.0 ## LSUF, r) \ + != copysign ## CSUF (10.0 ## LSUF, \ + tests_strto ## FSUF[i].expected))) \ + { \ + char buf1[FSTRLENMAX], buf2[FSTRLENMAX]; \ + FTOSTR (buf1, sizeof (buf1), "%g", r); \ + FTOSTR (buf2, sizeof (buf2), "%g", \ + tests_strto ## FSUF[i].expected); \ + printf ("%d: got wrong results %s, expected %s\n", \ + i, buf1, buf2); \ + status = 1; \ + } \ + } \ + \ + return status; \ +} +GEN_TEST_STRTOD_FOREACH (TEST_STRTOD) static int do_test (void) @@ -72,29 +132,7 @@ do_test (void) return 1; } - int status = 0; - - for (int i = 0; i < NTESTS; ++i) - { - char *ep; - double r = __strtod_internal (tests[i].in, &ep, tests[i].group); - - if (*ep != '\0') - { - printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); - status = 1; - } - - if (r != tests[i].expected - || copysign (10.0, r) != copysign (10.0, tests[i].expected)) - { - printf ("%d: got wrong results %g, expected %g\n", - i, r, tests[i].expected); - status = 1; - } - } - - return status; + return STRTOD_TEST_FOREACH (test_strto); } #include