1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Copyright 2025 Bill Sommerfeld 32 */ 33 34 #include "lint.h" 35 #include <errno.h> 36 #include <stdio.h> 37 #include <values.h> 38 #include <floatingpoint.h> 39 #include <stdlib.h> 40 #include <sys/types.h> 41 #include <xlocale.h> 42 #include "libc.h" 43 #include "xpg6.h" 44 45 double 46 strtod(const char *cp, char **ptr) 47 { 48 return (strtod_l(cp, ptr, uselocale(NULL))); 49 } 50 51 double 52 strtod_l(const char *cp, char **ptr, locale_t loc) 53 { 54 double x; 55 decimal_mode mr; 56 decimal_record dr; 57 fp_exception_field_type fs; 58 enum decimal_string_form form; 59 char *pechar; 60 int lc; 61 62 lc = (__xpg6 & _C99SUSv3_recognize_hexfp)? -1 : 0; 63 string_to_decimal_l((char **)&cp, MAXINT, lc, &dr, &form, &pechar, loc); 64 if (ptr != NULL) 65 *ptr = (char *)cp; 66 if (form == invalid_form) 67 return (0.0); /* Shameful kluge for SVID's sake. */ 68 #if defined(__sparc) 69 mr.rd = _QgetRD(); 70 #elif defined(__i386) || defined(__amd64) 71 mr.rd = __xgetRD(); 72 #else 73 #error Unknown architecture 74 #endif 75 if ((int)form < 0) 76 __hex_to_double(&dr, mr.rd, &x, &fs); 77 else 78 decimal_to_double(&x, &mr, &dr, &fs); 79 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 80 errno = ERANGE; 81 return (x); 82 } 83 84 float 85 strtof(const char *cp, char **ptr) 86 { 87 return (strtof_l(cp, ptr, uselocale(NULL))); 88 } 89 90 float 91 strtof_l(const char *cp, char **ptr, locale_t loc) 92 { 93 float x; 94 decimal_mode mr; 95 decimal_record dr; 96 fp_exception_field_type fs; 97 enum decimal_string_form form; 98 char *pechar; 99 100 string_to_decimal_l((char **)&cp, MAXINT, -1, &dr, &form, &pechar, loc); 101 if (ptr != NULL) 102 *ptr = (char *)cp; 103 if (form == invalid_form) 104 return (0.0f); 105 #if defined(__sparc) 106 mr.rd = _QgetRD(); 107 #elif defined(__i386) || defined(__amd64) 108 mr.rd = __xgetRD(); 109 #else 110 #error Unknown architecture 111 #endif 112 if ((int)form < 0) 113 __hex_to_single(&dr, mr.rd, &x, &fs); 114 else 115 decimal_to_single(&x, &mr, &dr, &fs); 116 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 117 errno = ERANGE; 118 return (x); 119 } 120 121 long double 122 strtold(const char *cp, char **ptr) 123 { 124 return (strtold_l(cp, ptr, uselocale(NULL))); 125 } 126 127 long double 128 strtold_l(const char *cp, char **ptr, locale_t loc) 129 { 130 long double x; 131 decimal_mode mr; 132 decimal_record dr; 133 fp_exception_field_type fs; 134 enum decimal_string_form form; 135 char *pechar; 136 137 string_to_decimal_l((char **)&cp, MAXINT, -1, &dr, &form, &pechar, loc); 138 if (ptr != NULL) 139 *ptr = (char *)cp; 140 if (form == invalid_form) 141 return (0.0L); 142 #if defined(__sparc) 143 mr.rd = _QgetRD(); 144 if ((int)form < 0) 145 __hex_to_quadruple(&dr, mr.rd, &x, &fs); 146 else 147 decimal_to_quadruple(&x, &mr, &dr, &fs); 148 #elif defined(__i386) || defined(__amd64) 149 mr.rd = __xgetRD(); 150 if ((int)form < 0) 151 __hex_to_extended(&dr, mr.rd, (extended *)&x, &fs); 152 else 153 decimal_to_extended((extended *)&x, &mr, &dr, &fs); 154 #else 155 #error Unknown architecture 156 #endif 157 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 158 errno = ERANGE; 159 return (x); 160 } 161