LCOV - code coverage report
Current view: top level - src/tds/unittests - numeric.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 54 59 91.5 %
Date: 2024-04-20 12:53:58 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 2005   Frediano Ziglio
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Library General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2 of the License, or (at your option) any later version.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Library General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Library General Public
      15             :  * License along with this library; if not, write to the
      16             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  * Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : #include "common.h"
      21             : #include <freetds/convert.h>
      22             : #include <assert.h>
      23             : 
      24             : /* test numeric scale */
      25             : 
      26             : static int g_result = 0;
      27             : static TDSCONTEXT ctx;
      28             : 
      29             : static void
      30         624 : test0(const char *src, int prec, int scale, int prec2, unsigned char scale2)
      31             : {
      32             :         int i;
      33             :         char buf[256];
      34             :         char result[256];
      35             :         char *p;
      36             :         CONV_RESULT cr;
      37             :         TDS_NUMERIC num;
      38             : 
      39             :         /* get initial number */
      40         624 :         memset(&cr.n, 0, sizeof(cr.n));
      41         624 :         cr.n.precision = prec;
      42         624 :         cr.n.scale = scale;
      43         624 :         if (tds_convert(&ctx, SYBVARCHAR, src, (TDS_UINT)strlen(src), SYBNUMERIC, &cr) < 0) {
      44           0 :                 fprintf(stderr, "Error getting numeric %s(%d,%d)\n", src, prec, scale);
      45           0 :                 exit(1);
      46             :         }
      47         624 :         num = cr.n;
      48             : 
      49             :         /* change scale with string */
      50         624 :         tds_numeric_to_string(&num, buf);
      51        1600 :         while ((p = strchr(buf, '.')) != NULL)
      52         352 :                 memmove(p, p+1, strlen(p));
      53             : 
      54        2368 :         for (i = 0; i < (scale2 - scale); ++i)
      55        2368 :                 strcat(buf, "0");
      56        1584 :         for (i = 0; i < (scale - scale2); ++i) {
      57        1584 :                 assert(strlen(buf) > 1);
      58        1584 :                 buf[strlen(buf)-1] = 0;
      59             :         }
      60         624 :         if (scale2) {
      61         584 :                 size_t len = strlen(buf);
      62         584 :                 assert(len > scale2);
      63         584 :                 memmove(buf + len - scale2 + 1, buf + len - scale2, scale2 + 1);
      64         584 :                 buf[len-scale2] = '.';
      65             :         }
      66         624 :         cr.n.precision = prec2;
      67         624 :         cr.n.scale = scale2;
      68         624 :         if (tds_convert(&ctx, SYBVARCHAR, src, (TDS_UINT)strlen(src), SYBNUMERIC, &cr) < 0)
      69         208 :                 strcpy(buf, "error");
      70             : 
      71             :         /* change scale with function */
      72         624 :         if (tds_numeric_change_prec_scale(&num, prec2, scale2) < 0)
      73         208 :                 strcpy(result, "error");
      74             :         else
      75         416 :                 tds_numeric_to_string(&num, result);
      76             : 
      77         624 :         if (strcmp(buf, result) != 0) {
      78           0 :                 fprintf(stderr, "Failed! %s (%d,%d) -> (%d,%d)\n\tshould be %s\n\tis %s\n",
      79             :                         src, prec, scale, prec2, scale2, buf, result);
      80           0 :                 g_result = 1;
      81           0 :                 exit(1);
      82             :         } else {
      83         624 :                 printf("%s -> %s ok!\n", src, buf);
      84             :         }
      85         624 : }
      86             : 
      87             : static void
      88             : test(const char *src, int prec, int scale, int scale2)
      89             : {
      90         568 :         test0(src, prec, scale, prec, scale2);
      91             : }
      92             : 
      93             : int
      94           8 : main(void)
      95             : {
      96             :         int i;
      97           8 :         memset(&ctx, 0, sizeof(ctx));
      98             : 
      99             :         /* increase scale */
     100          88 :         for (i = 0; i < 10; ++i) {
     101         160 :                 test("1234", 18+i, 0, 2+i);
     102         160 :                 test("1234.1234", 18+i, 5, 3+i);
     103         160 :                 test("1234.1234", 22+i, 5+i, 12+i);
     104             :         }
     105             : 
     106             :         /* overflow */
     107           8 :         test("1234", 4, 0, 2);
     108          96 :         for (i = 1; i < 12; ++i)
     109         176 :                 test("1234", 3+i, 0, i);
     110          80 :         for (i = 2; i < 12; ++i)
     111         160 :                 test("1234", 2+i, 0, i);
     112             : 
     113             :         /* decrease scale */
     114           8 :         test("1234", 10, 4, 0);
     115         152 :         for (i = 2; i < 20; ++i)
     116         144 :                 test("1234.765", 30, 20, i);
     117             : 
     118           8 :         test0("765432.2", 30, 2, 20, 2);
     119           8 :         test0("765432.2", 30, 2, 40, 2);
     120           8 :         test0("765432.2", 30, 2, 6, 2);
     121             : 
     122             :         /* test big overflows */
     123           8 :         test0("10000000000000000000000000", 30, 0, 10, 0);
     124           8 :         test0("1000000000000000000", 30, 0, 10, 0);
     125             : 
     126           8 :         test0("10000000000000000", 30, 10, 19, 0);
     127           8 :         test0("10000000000000000", 30, 10, 12, 0);
     128             : 
     129             : #if 0
     130             :         {
     131             :                 int p1, s1, p2, s2;
     132             :                 for (p1 = 1; p1 <= 77; ++p1) {
     133             :                         printf("(%d,%d) -> (%d,%d)\n", p1, s1, p2, s2);
     134             :                         for (s1 = 0; s1 < p1; ++s1)
     135             :                                 for (p2 = 1; p2 <= 77; ++p2)
     136             :                                         for (s2 = 0; s2 < p2; ++s2)
     137             :                                                 test0("9", p1, s1, p2, s2);
     138             :                 }
     139             :         }
     140             : #endif
     141             : 
     142           8 :         if (!g_result)
     143           8 :                 printf("All passed!\n");
     144             : 
     145           8 :         return g_result;
     146             : }

Generated by: LCOV version 1.13