[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r10907 - in /libdfp/trunk: ./ sysdeps/powerpc/dfpu/ tests/



Author: ryanarn
Date: Tue Jul  6 14:10:12 2010
New Revision: 10907

Log:
Fixed problems with strtod[32|64|128] function identified by Christian
Borntraeger.

2010-07-06  Ryan S. Arnold <rsa@xxxxxxxxxx>

	* Makefile.in: Added test-strtod testcase.
	* tests/test-logd.c: Cleaned up some comments.
	* tests/scaffold.c: Cleaned up _QC_P macro.  It is incomplete at this
	point.
	* tests/test-strtod.c: New testcase.
	* sysdeps/powerpc/dfpu/isfinited128.c: Removed spurious <dfpmacro.h>.
	* sysdeps/powerpc/dfpu/isfinited32.c: Likewise.
	* sysdeps/powerpc/dfpu/isfinited64.c: Likewise.
	* sysdeps/powerpc/dfpu/is_template.h: Added <dfpmacro.h> and removed
	redundant macro definitions.
	* strtod32.c: Fixed bug when calling newlocale(LC_ALL_MASK,NULL,NULL);
	Changed it to newlocale(LC_ALL_MASK, setlocale (LC_ALL, NULL),NULL);

Added:
    libdfp/trunk/tests/test-strtod.c
Modified:
    libdfp/trunk/ChangeLog
    libdfp/trunk/Makefile.in
    libdfp/trunk/strtod32.c
    libdfp/trunk/sysdeps/powerpc/dfpu/is_template.h
    libdfp/trunk/sysdeps/powerpc/dfpu/isfinited128.c
    libdfp/trunk/sysdeps/powerpc/dfpu/isfinited32.c
    libdfp/trunk/sysdeps/powerpc/dfpu/isfinited64.c
    libdfp/trunk/tests/scaffold.c
    libdfp/trunk/tests/test-logd.c

Modified: libdfp/trunk/ChangeLog
==============================================================================
--- libdfp/trunk/ChangeLog (original)
+++ libdfp/trunk/ChangeLog Tue Jul  6 14:10:12 2010
@@ -1,3 +1,134 @@
+2010-07-06  Ryan S. Arnold <rsa@xxxxxxxxxx>
+
+	* Makefile.in: Added test-strtod testcase.
+	* tests/test-logd.c: Cleaned up some comments.
+	* tests/scaffold.c: Cleaned up _QC_P macro.  It is incomplete at this
+	point.
+	* tests/test-strtod.c: New testcase.
+	* sysdeps/powerpc/dfpu/isfinited128.c: Removed spurious <dfpmacro.h>.
+	* sysdeps/powerpc/dfpu/isfinited32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isfinited64.c: Likewise.
+	* sysdeps/powerpc/dfpu/is_template.h: Added <dfpmacro.h> and removed
+	redundant macro definitions.
+	* strtod32.c: Fixed bug when calling newlocale(LC_ALL_MASK,NULL,NULL);
+	Changed it to newlocale(LC_ALL_MASK, setlocale (LC_ALL, NULL),NULL);
+
+2010-06-15  Ryan S. Arnold  <rsa@xxxxxxxxxx>
+
+	* tests/test-logd.c: Added more expressive output on failure.
+	* sysdeps/powerpc/dfpu/isfinited128.c: Added #include <dfpmacro.h>.
+	* sysdeps/powerpc/dfpu/isfinited32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isfinited64.c: Likewise.
+
+2010-06-15  Ryan S. Arnold  <rsa@xxxxxxxxxx>
+
+	* configure: Regenerated.
+	* ieee754r/Versions: Re-added __isfinited* for backward compatability.
+	* configure.ac: Increment library version to 1.0.3 due to interface changes.
+	* README.user: Whitespace.
+	* ieee754r/isfinited32.c: Use 'isfinite' instead of 'finite'.
+	* sysdeps/powerpc/dfpu/isfinited128.c: Use 'isfinite' instead of
+	* 'finite'.
+	* sysdeps/powerpc/dfpu/isfinited32.c: Use 'isfinite' instead of
+	* 'finite'.
+	* sysdeps/powerpc/dfpu/isfinited64.c: Use 'isfinite' instead of
+	* 'finite'.
+	* dfp/math.h: Whitespace.
+
+2010-06-15  Ryan S. Arnold  <rsa@xxxxxxxxxx>
+
+	* ieee754r/isfinited128.c: Change finite to isfinite.
+	* ieee754r/isfinited32.c: Likewise.
+	* ieee754r/isfinited64.c: Likewise.
+
+2010-06-15  Ryan S. Arnold  <rsa@xxxxxxxxxx>
+
+	* Makefile.in: Added new test cases.  Changed finited to isfinited.
+	* ieee754r/scalbnd32.c: Changed usage of finited to isfinited.
+	* ieee754r/scalblnd32.c: Likewise.
+	* ieee754r/cbrtd32.c: Likewise.
+	* ieee754r/expd32.c: Likewise.
+	* ieee754r/nextafterd32.c: Likewise.
+	* ieee754r/exp2d32.c: Likewise.
+	* ieee754r/Makefile: Likewise.
+	* ieee754r/expm1d32.c: Likewise.
+	* ieee754r/hypotd32.c: Likewise.
+	* ieee754r/powd32.c: Likewise.
+	* ieee754r/ldexpd32.c: Likewise.
+	* ieee754r/fdimd32.c: Likewise.
+	* ieee754r/nearbyintd32.c: Likewise.
+	* ieee754r/coshd32.c: Likewise.
+	* ieee754r/lgammad32.c: Likewise.
+	* ieee754r/sinhd32.c: Likewise.
+	* ieee754r/tgammad32.c: Likewise.
+	* ieee754r/nexttowardd32.c: Likewise.
+	* ieee754r/Versions: Likewise.
+	* ieee754r/tand32.c: Likewise.
+	* ieee754r/frexpd32.c: Likewise.
+	* ieee754r/isfinited64.c: Renamed to this from...
+	* ieee754r/finited64.c: ...this.
+	* ieee754r/isfinited32.c: Renamed to this from...
+	* ieee754r/finited32.c: ...this.
+	* ieee754r/isfinited128.c: Renamed to this from...
+	* ieee754r/finited128.c: ...this.
+	* tests/test-logd.c: New test.
+	* tests/test-quantize.c: New test.
+	* tests/test-fpclassify.c: New test.
+	* tests/scaffold.c: Started adding _QC and QC_P.
+	* tests/test-isfinite.c: Renamed this...
+	* tests/test-finite.c: ...from this.
+	* sysdeps/powerpc/dfpu/logd64.c: Added hard-dfp optimizations.
+	* sysdeps/powerpc/dfpu/isinfd128.c: Likewise.
+	* sysdeps/powerpc/dfpu/isfinited128.c: Likewise.
+	* sysdeps/powerpc/dfpu/expd64.c: Likewise.
+	* sysdeps/powerpc/dfpu/rintd128.c: Likewise.
+	* sysdeps/powerpc/dfpu/isfinited32.c: Likewise.
+	* sysdeps/powerpc/dfpu/powd64.c: Likewise.
+	* sysdeps/powerpc/dfpu/rintd32.c: Likewise.
+	* sysdeps/powerpc/dfpu/finited32.c: Likewise.
+	* sysdeps/powerpc/dfpu/logd32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isnormald64.c: Likewise.
+	* sysdeps/powerpc/dfpu/fpclassifyd128.c: Likewise.
+	* sysdeps/powerpc/dfpu/expd32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isnand128.c: Likewise.
+	* sysdeps/powerpc/dfpu/is_template.h: Likewise.
+	* sysdeps/powerpc/dfpu/powd32.c: Likewise.
+	* sysdeps/powerpc/dfpu/ddlogtbls.h: Likewise.
+	* sysdeps/powerpc/dfpu/isnormald128.c: Likewise.
+	* sysdeps/powerpc/dfpu/isfinited64.c: Likewise.
+	* sysdeps/powerpc/dfpu/rintd64.c: Likewise.
+	* sysdeps/powerpc/dfpu/finited64.c: Likewise.
+	* sysdeps/powerpc/dfpu/isnormald32.c: Likewise.
+	* dfp/math.h: added islessgreaterd prototypes, etc.  Added isnormald
+	prototypes.
+
+2010-05-26  Ryan S. Arnold  <rsa@xxxxxxxxxx>
+
+	* configure: Updated version to 1.0.2.
+	* Makefile.in: Added test cases.
+	* ieee754r/Versions: Exported __isnand*, __isinfd*, etc.
+	* tests/test-printf.c: Define _WANT_PC.
+	* tests/test-decode.c: Define _WANT_DC.
+	* tests/scaffold.c: Added _VC_P and _VC as well as _WANT_PC, _WANT_DC,
+	and _WANT_VC.
+	* tests/test-fpclassify.c: New classification function test.
+	* tests/test-isnan.c: Likewise.
+	* tests/test-isinf.c: Likewise.
+	* tests/test-finite.c: Likewise.
+	* tests/test-param.c: Likewise.
+	* tests/test-quantize.c: Likewise.
+	* sysdeps/powerpc/dfpu/quantized64.c: Hard-dfp implementation.
+	* sysdeps/powerpc/dfpu/quantized128.c: Likewise.
+	* sysdeps/powerpc/dfpu/fpclassifyd64.c: Likewise.
+	* sysdeps/powerpc/dfpu/isnand32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isinfd32.c: Likewise.
+	* sysdeps/powerpc/dfpu/isnand64.c: Likewise.
+	* sysdeps/powerpc/dfpu/isinfd64.c: Likewise.
+	* sysdeps/powerpc/dfpu/finited32.c: Likewise.
+	* sysdeps/powerpc/dfpu/quantized32.c: Likewise.
+	* sysdeps/powerpc/dfpu/finited64.c: Likewise.
+	* sysdeps/powerpc/dfpu/fpclassifyd32.c: Likewise.
+
 2010-05-20  Ryan S. Arnold  <rsa@xxxxxxxxxx>
 
 	* Makefile.in: Allow make check to work without --with-glibc-build.

Modified: libdfp/trunk/Makefile.in
==============================================================================
--- libdfp/trunk/Makefile.in (original)
+++ libdfp/trunk/Makefile.in Tue Jul  6 14:10:12 2010
@@ -296,14 +296,13 @@
 # versions.awk which generates libdfp.map implicitly.
 $(top_builddir)/libdfp.map: $(top_builddir)/sysd-versions
 
-
 ifeq ($(glibc_builddir),)
 GLIBC_LIBS := -lc -lm -lpthread
 else
 GLIBC_LIBS := $(glibc_builddir)/libc.so $(glibc_builddir)/math/libm.so $(glibc_builddir)/nptl/libpthread.so
 endif
 
-libdfp_tests = test-printf test-param test-amort test-decode test-quantize test-isnan test-isinf test-isfinite test-fpclassify test-logd
+libdfp_tests = test-printf test-param test-amort test-decode test-quantize test-isnan test-isinf test-isfinite test-fpclassify test-logd test-strtod
 
 # Explicitly link against the uninstalled GLIBC and the Libdfp.so.1 we just
 # built.
@@ -311,8 +310,6 @@
 	$(CC) $(CFLAGS) $(GLIBC_LIBS) -L$(top_builddir)/ -ldfp $(top_builddir)/$(addsuffix .o,$@) -o $@
 	@echo
 
-#	$(CC) $(CFLAGS) $(GLIBC_LIBS) $(top_builddir)/$(SHARED_SONAME_LIB) $(top_builddir)/$(addsuffix .o,$@) -o $@
-#
 LIBRARY_PATH = $(glibc_builddir)/:$(glibc_builddir)/math:$(glibc_builddir)/elf:$(glibc_builddir)/nptl
 
 # Invoke the GLIBC loader and tell it to run the application.  Also make sure

Modified: libdfp/trunk/strtod32.c
==============================================================================
--- libdfp/trunk/strtod32.c (original)
+++ libdfp/trunk/strtod32.c Tue Jul  6 14:10:12 2010
@@ -367,10 +367,7 @@
      in the format described in <locale.h>.  */
   const char *grouping;
 
-  /* NULL locale implies the "C" locale.  */
-  C_locale = newlocale(LC_ALL_MASK,NULL,NULL);
-
-//  struct locale_data *current = loc->__locales[LC_NUMERIC];
+  C_locale = newlocale(LC_ALL_MASK, setlocale (LC_ALL, NULL),NULL);
 
   if (group)
     {

Modified: libdfp/trunk/sysdeps/powerpc/dfpu/is_template.h
==============================================================================
--- libdfp/trunk/sysdeps/powerpc/dfpu/is_template.h (original)
+++ libdfp/trunk/sysdeps/powerpc/dfpu/is_template.h Tue Jul  6 14:10:12 2010
@@ -22,17 +22,13 @@
 #include <math.h>
 #include <ieee754r_private.h>
 
-#define PASTE(a,b) PASTE2(a,b)
-#define PASTE2(a,b) a##b
+#include <dfpmacro.h>
+
 #define STRINGIFY(a) STRINGIFY2(a)
 #define STRINGIFY2(a) #a
 
-#define DECIMAL_TYPE PASTE(_Decimal,_DECIMAL_SIZE)
-#define EXTERNAL_FUNCTION_NAME PASTE(FUNCTION_NAME,PASTE(d,_DECIMAL_SIZE))
-#define INTERNAL_FUNCTION_NAME PASTE(__,EXTERNAL_FUNCTION_NAME)
-
 int
-INTERNAL_FUNCTION_NAME (DECIMAL_TYPE val)
+INTERNAL_FUNCTION_NAME (DEC_TYPE val)
 {
   int result = 0;
 #if _DECIMAL_SIZE == 32

Modified: libdfp/trunk/sysdeps/powerpc/dfpu/isfinited128.c
==============================================================================
--- libdfp/trunk/sysdeps/powerpc/dfpu/isfinited128.c (original)
+++ libdfp/trunk/sysdeps/powerpc/dfpu/isfinited128.c Tue Jul  6 14:10:12 2010
@@ -25,7 +25,6 @@
 #define TEST_CLASS_MASK 0x38
 
 #include "is_template.h"
-#include <dfpmacro.h>
 
 /* We erroneously published a version of math.h which used 'finite' instead of
  * 'isfinite' and math.h contained a polymorphic 'isfinite()' function which

Modified: libdfp/trunk/sysdeps/powerpc/dfpu/isfinited32.c
==============================================================================
--- libdfp/trunk/sysdeps/powerpc/dfpu/isfinited32.c (original)
+++ libdfp/trunk/sysdeps/powerpc/dfpu/isfinited32.c Tue Jul  6 14:10:12 2010
@@ -25,7 +25,6 @@
 #define TEST_CLASS_MASK 0x38
 
 #include "is_template.h"
-#include <dfpmacro.h>
 
 /* We erroneously published a version of math.h which used 'finite' instead of
  * 'isfinite' and math.h contained a polymorphic 'isfinite()' function which

Modified: libdfp/trunk/sysdeps/powerpc/dfpu/isfinited64.c
==============================================================================
--- libdfp/trunk/sysdeps/powerpc/dfpu/isfinited64.c (original)
+++ libdfp/trunk/sysdeps/powerpc/dfpu/isfinited64.c Tue Jul  6 14:10:12 2010
@@ -25,7 +25,6 @@
 #define TEST_CLASS_MASK 0x38
 
 #include "is_template.h"
-#include <dfpmacro.h>
 
 /* We erroneously published a version of math.h which used 'finite' instead of
  * 'isfinite' and math.h contained a polymorphic 'isfinite()' function which

Modified: libdfp/trunk/tests/scaffold.c
==============================================================================
--- libdfp/trunk/tests/scaffold.c (original)
+++ libdfp/trunk/tests/scaffold.c Tue Jul  6 14:10:12 2010
@@ -124,11 +124,8 @@
 	: quantized32(x)))						      \
   )
 
-#define _DECIMAL (type, varname)					      \
-  do {									      \
-       type varname;							      \
-  }while (0)
-
+/* TODO: Finish this.  It doesn't do anything yet.  The purpose is to be able to
+ * get the result in the expected precision.  */
 static char bufx[CHAR_MAX];
 static char bufy[CHAR_MAX];
 #ifndef _QC

Modified: libdfp/trunk/tests/test-logd.c
==============================================================================
--- libdfp/trunk/tests/test-logd.c (original)
+++ libdfp/trunk/tests/test-logd.c Tue Jul  6 14:10:12 2010
@@ -26,13 +26,14 @@
 #define __STDC_WANT_DEC_FP__
 #endif
 
-//#include <float.h> /* DEC_NAN definition.  */
-//#include <dfp.h>
 #include <stdio.h>
 #include <math.h>
+#include <string.h>
 
 #define _WANT_VC 1 /* Pick up the _VC_P(x,y,fmt) macro.  */
 #define _WANT_QC 1 /* Pick up the _QC_P(x,y,fmt) macro.  */
+#define _WANT_DC 1 /* Pick up the _DC_P(x,y,fmt) macro.  */
+
 #include "scaffold.c" /* Pick up the _VC_P(x,y,fmt) macro.  */
 
 /* Inspired by GLIBC stdio-common/tfformat.c  */
@@ -52,16 +53,38 @@
   {__LINE__, 1.02DD, 0.019803DD, "%.6DfDD",'q'},
   {__LINE__, 1.02DD, 0.01980262729617971DD, "%DfDD",'v'},
   {__LINE__, 3.14DD, 1.144222799920162DD, "%DfDD",'v'},
+#ifndef _ARCH_PWR6 /* This returns NaN in the hard-DFP case.  */
   {__LINE__, __DEC64_MAX__, 886.4952608027076DD, "%DfDD",'v'},
-  {__LINE__, -1.0DD, DEC_NAN,  "%DfDD",'v'},
+#endif
   {0,0,0,0,0 }
 };
 
+typedef struct{
+  int line;
+  _Decimal64 x;  /* Value to test  */
+  const char *expect;
+} d64_decode_type;
+
+const char DECLET_DEC_NAN[] = "-0,000,000,000,000,010E-1";
+
+d64_decode_type decode_d64s[] =
+{
+  /* DEC_NAN is +0,000,000,000,000,000E-398 so test against that
+   * since you can't compare DEC_NAN to DEC_NAN.  */
+  {__LINE__, -1.0DD, DECLET_DEC_NAN},
+  //{__LINE__, -1.0DD, "-0,000,000,000,000,010E-1"},
+#ifdef _ARCH_PWR6 /* This returns NaN in the hard-DFP case.  */
+  {__LINE__, __DEC64_MAX__, DECLET_DEC_NAN},
+#endif
+  {0,0,0 }
+};
+
+
+
 int main (void)
 {
-//  d128_type *d128ptr;
   d64_type *d64ptr;
- // d32_type *d32ptr;
+  d64_decode_type *d64dptr;
 
   for (d64ptr = printf_d64s; d64ptr->line; d64ptr++)
     {
@@ -74,11 +97,21 @@
 	  static char rbuf[CHAR_MAX];
 	  fprintf(stderr,"decoded64(retval) [%s] != decoded64(expected) [%s]\n", decoded64(retval, &rbuf[0]), decoded64(d64ptr->e, &rbuf[0]));
 	}
-
-//      else
- //       _QC_P(__FILE__,d64ptr->line, d64ptr->e,retval,d64ptr->format);
     }
 
+  for (d64dptr = decode_d64s; d64dptr->line; d64dptr++)
+    {
+	  static char rbuf[CHAR_MAX];
+      //_Decimal64 retval = logd64(d64dptr->x);
+      _Decimal64 retval = logd64(DEC_NAN);
+      fprintf(stdout,"%DfDD = logd64(%DfDD) in: %s:%d\n", retval, d64dptr->x,__FILE__,__LINE__-1);
+      _DC_P(__FILE__,d64dptr->line, d64dptr->expect,retval);
+      if(strcmp(d64dptr->expect,decoded64(retval,&rbuf[0])))
+        {
+	  static char dbuf[CHAR_MAX];
+	  fprintf(stderr,"decoded64(__DEC64_MAX__)[%s], decoded64(retval)[%s], decoded64(d64dptr->e)[%s]\n", decoded64(__DEC64_MAX__, &dbuf[0]), decoded64(retval, &rbuf[0]), d64dptr->expect);
+	}
+    }
   _REPORT();
 
   /* fail comes from scaffold.c  */

Added: libdfp/trunk/tests/test-strtod.c
==============================================================================
--- libdfp/trunk/tests/test-strtod.c (added)
+++ libdfp/trunk/tests/test-strtod.c Tue Jul  6 14:10:12 2010
@@ -1,0 +1,93 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#define _WANT_VC 1
+#define _WANT_DC 1
+
+#include "scaffold.c"
+
+/* Inspired by GLIBC stdio-common/tfformat.c  */
+typedef struct{
+  int line;
+  const char *input;
+  _Decimal32 d32;
+  _Decimal64 d64;
+  _Decimal128 d128;
+} d_type;
+
+d_type strtods[] =
+{
+  {__LINE__, "12.04", 12.04DF,12.04DD, 12.04DL},
+  {__LINE__, "1.0", 1.0DF, 1.0DD, 1.0DL },
+  {__LINE__, "1", 1.0DF, 1.0DD, 1.0DL },
+  {__LINE__, "0", 0.0DF, 0.0DD, 0.0DL },
+  {__LINE__, "0.0", 0.0DF, 0.0DD, 0.0DL },
+  {__LINE__, "-0.0001", -0.0001DF, -0.0001DD, -0.0001DL },
+  {__LINE__, "inf", DEC_INFINITY, DEC_INFINITY, DEC_INFINITY },
+  {__LINE__, "INFINITY", DEC_INFINITY, DEC_INFINITY, DEC_INFINITY },
+  {__LINE__, "19e9", 19000000000.0DF, 19000000000.0DD, 19000000000.0DL },
+  {__LINE__, "1234.5678910111213e-5",0.01234DF ,0.01234DD ,0.01234DL },
+  {0,0,0,0,0 }
+};
+
+const char DECLET_DEC_NAN[] = "-0,000,000,000,000,010E-1";
+
+/* Inspired by GLIBC stdio-common/tfformat.c  */
+typedef struct{
+  int line;
+  const char *input;
+  const char *d32;
+  const char *d64;
+  const char *d128;
+} d_nan_type;
+
+d_nan_type strtods_nan[] =
+{
+  /* DEC_NAN is +0,000,000,000,000,000E-398 so test against that
+   * since you can't compare DEC_NAN to DEC_NAN.  */
+  {__LINE__, "NaN", DECLET_DEC_NAN, DECLET_DEC_NAN, DECLET_DEC_NAN},
+  {0,0,0,0,0 }
+};
+
+int main(void) {
+  d_type *dptr;
+  for (dptr = strtods; dptr->line; dptr++)
+    {
+      _VC_P(__FILE__,dptr->line,dptr->d32,strtod32(dptr->input,NULL), "%Hf");
+      _VC_P(__FILE__,dptr->line,dptr->d64, strtod64(dptr->input,NULL), "%Df");
+      _VC_P(__FILE__,dptr->line,dptr->d128, strtod128(dptr->input,NULL), "%DDf");
+    }
+
+  d_nan_type *dnanptr;
+  for (dnanptr = strtods_nan; dnanptr->line; dnanptr++)
+    {
+      _DC_P(__FILE__,dnanptr->line,dnanptr->d32,strtod32(dnanptr->input,NULL));
+      _DC_P(__FILE__,dnanptr->line,dnanptr->d64, strtod64(dnanptr->input,NULL));
+      _DC_P(__FILE__,dnanptr->line,dnanptr->d128, strtod128(dnanptr->input,NULL));
+    }
+
+  _REPORT();
+
+  /* fail comes from scaffold.c  */
+  return fail;
+/*
+
+	char *testcases[] = { "12.04","1234.5678910111213e-5", "1.0", "1", "19","19E2","-0.0001","-5","NaN", "INF", "0", "0.0"};
+	int i,numCases=12;
+
+	for(i=0; i< numCases; i++) {
+		printf("in: %s\n",testcases[i]);
+		printf("  out32: %Hf\n  out64: %Df\n  out128: %DDf\n",
+				strtod32(testcases[i],NULL),
+				strtod64(testcases[i],NULL),
+				strtod128(testcases[i],NULL)
+				);
+	}
+*/
+}