Pull in some of the lpt_port_test fixes from lpt.c.
[unix-history] / usr.bin / f2c / cds.c
CommitLineData
f1525c23
WH
1/****************************************************************
2Copyright 1990, 1993 by AT&T Bell Laboratories and Bellcore.
3
4Permission to use, copy, modify, and distribute this software
5and its documentation for any purpose and without fee is hereby
6granted, provided that the above copyright notice appear in all
7copies and that both that the copyright notice and this
8permission notice and warranty disclaimer appear in supporting
9documentation, and that the names of AT&T Bell Laboratories or
10Bellcore or any of their entities not be used in advertising or
11publicity pertaining to distribution of the software without
12specific, written prior permission.
13
14AT&T and Bellcore disclaim all warranties with regard to this
15software, including all implied warranties of merchantability
16and fitness. In no event shall AT&T or Bellcore be liable for
17any special, indirect or consequential damages or any damages
18whatsoever resulting from loss of use, data or profits, whether
19in an action of contract, negligence or other tortious action,
20arising out of or in connection with the use or performance of
21this software.
22****************************************************************/
23
24/* Put strings representing decimal floating-point numbers
25 * into canonical form: always have a decimal point or
26 * exponent field; if using an exponent field, have the
27 * number before it start with a digit and decimal point
28 * (if the number has more than one digit); only have an
29 * exponent field if it saves space.
30 *
31 * Arrange that the return value, rv, satisfies rv[0] == '-' || rv[-1] == '-' .
32 */
33
34#include "sysdep.h"
35
36 char *
37cds(s, z0)
38 char *s, *z0;
39{
40 int ea, esign, et, i, k, nd = 0, sign = 0, tz;
41 char c, *z;
42 char ebuf[24];
43 long ex = 0;
44 static char etype[Table_size], *db;
45 static int dblen = 64;
46
47 if (!db) {
48 etype['E'] = 1;
49 etype['e'] = 1;
50 etype['D'] = 1;
51 etype['d'] = 1;
52 etype['+'] = 2;
53 etype['-'] = 3;
54 db = Alloc(dblen);
55 }
56
57 while((c = *s++) == '0');
58 if (c == '-')
59 { sign = 1; c = *s++; }
60 else if (c == '+')
61 c = *s++;
62 k = strlen(s) + 2;
63 if (k >= dblen) {
64 do dblen <<= 1;
65 while(k >= dblen);
66 free(db);
67 db = Alloc(dblen);
68 }
69 if (etype[(unsigned char)c] >= 2)
70 while(c == '0') c = *s++;
71 tz = 0;
72 while(c >= '0' && c <= '9') {
73 if (c == '0')
74 tz++;
75 else {
76 if (nd)
77 for(; tz; --tz)
78 db[nd++] = '0';
79 else
80 tz = 0;
81 db[nd++] = c;
82 }
83 c = *s++;
84 }
85 ea = -tz;
86 if (c == '.') {
87 while((c = *s++) >= '0' && c <= '9') {
88 if (c == '0')
89 tz++;
90 else {
91 if (tz) {
92 ea += tz;
93 if (nd)
94 for(; tz; --tz)
95 db[nd++] = '0';
96 else
97 tz = 0;
98 }
99 db[nd++] = c;
100 ea++;
101 }
102 }
103 }
104 if (et = etype[(unsigned char)c]) {
105 esign = et == 3;
106 c = *s++;
107 if (et == 1) {
108 if(etype[(unsigned char)c] > 1) {
109 if (c == '-')
110 esign = 1;
111 c = *s++;
112 }
113 }
114 while(c >= '0' && c <= '9') {
115 ex = 10*ex + (c - '0');
116 c = *s++;
117 }
118 if (esign)
119 ex = -ex;
120 }
121 switch(c) {
122 case 0:
123 break;
124#ifndef VAX
125 case 'i':
126 case 'I':
127 Fatal("Overflow evaluating constant expression.");
128 case 'n':
129 case 'N':
130 Fatal("Constant expression yields NaN.");
131#endif
132 default:
133 Fatal("unexpected character in cds.");
134 }
135 ex -= ea;
136 if (!nd) {
137 if (!z0)
138 z0 = mem(4,0);
139 strcpy(z0, "-0.");
140 sign = 0;
141 }
142 else if (ex > 2 || ex + nd < -2) {
143 sprintf(ebuf, "%ld", ex + nd - 1);
144 k = strlen(ebuf) + nd + 3;
145 if (nd > 1)
146 k++;
147 if (!z0)
148 z0 = mem(k,0);
149 z = z0;
150 *z++ = '-';
151 *z++ = *db;
152 if (nd > 1) {
153 *z++ = '.';
154 for(k = 1; k < nd; k++)
155 *z++ = db[k];
156 }
157 *z++ = 'e';
158 strcpy(z, ebuf);
159 }
160 else {
161 k = (int)(ex + nd);
162 i = nd + 3;
163 if (k < 0)
164 i -= k;
165 else if (ex > 0)
166 i += ex;
167 if (!z0)
168 z0 = mem(i,0);
169 z = z0;
170 *z++ = '-';
171 if (ex >= 0) {
172 for(k = 0; k < nd; k++)
173 *z++ = db[k];
174 while(--ex >= 0)
175 *z++ = '0';
176 *z++ = '.';
177 }
178 else {
179 for(i = 0; i < k;)
180 *z++ = db[i++];
181 *z++ = '.';
182 while(++k <= 0)
183 *z++ = '0';
184 while(i < nd)
185 *z++ = db[i++];
186 }
187 *z = 0;
188 }
189 return sign ? z0 : z0+1;
190 }