|
3 | 3 | * numutils.c |
4 | 4 | * utility functions for I/O of built-in numeric types. |
5 | 5 | * |
6 | | - *integer:pg_itoa, pg_ltoa |
7 | | - *floating point:ftoa, atof1 |
| 6 | + *integer:pg_atoi, pg_itoa, pg_ltoa |
8 | 7 | * |
9 | 8 | * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group |
10 | 9 | * Portions Copyright (c) 1994, Regents of the University of California |
11 | 10 | * |
12 | 11 | * |
13 | 12 | * IDENTIFICATION |
14 | | - * $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.60 2004/01/07 18:56:28 neilc Exp $ |
| 13 | + * $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.61 2004/02/18 00:01:33 neilc Exp $ |
15 | 14 | * |
16 | 15 | *------------------------------------------------------------------------- |
17 | 16 | */ |
@@ -147,334 +146,3 @@ pg_ltoa(int32 l, char *a) |
147 | 146 | { |
148 | 147 | sprintf(a,"%d",l); |
149 | 148 | } |
150 | | - |
151 | | -/* |
152 | | - ** ftoa- FLOATING POINT TO ASCII CONVERSION |
153 | | - ** |
154 | | - **CODE derived from ingres, ~ingres/source/gutil/ftoa.c |
155 | | - ** |
156 | | - **'Value' is converted to an ascii character string and stored |
157 | | - **into 'ascii'. Ascii should have room for at least 'width' + 1 |
158 | | - **characters. 'Width' is the width of the output field (max). |
159 | | - **'Prec' is the number of characters to put after the decimal |
160 | | - **point.The format of the output string is controlled by |
161 | | - **'format'. |
162 | | - ** |
163 | | - **'Format' can be: |
164 | | - **e or E: "E" format output |
165 | | - **f or F: "F" format output |
166 | | - **g or G: "F" format output if it will fit, otherwise |
167 | | - **use "E" format. |
168 | | - **n or N: same as G, but decimal points will not always |
169 | | - **be aligned. |
170 | | - ** |
171 | | - **If 'format' is upper case, the "E" comes out in upper case; |
172 | | - **otherwise it comes out in lower case. |
173 | | - ** |
174 | | - **When the field width is not big enough, it fills the field with |
175 | | - **stars ("*****") and returns zero. Normal return is the width |
176 | | - **of the output field (sometimes shorter than 'width'). |
177 | | - */ |
178 | | -#ifdefNOT_USED |
179 | | -int |
180 | | -ftoa(doublevalue,char*ascii,intwidth,intprec1,charformat) |
181 | | -{ |
182 | | -#ifndefHAVE_FCVT |
183 | | -charout[256]; |
184 | | -charfmt[256]; |
185 | | -intret; |
186 | | - |
187 | | -sprintf(fmt,"%%%d.%d%c",width,prec1,format); |
188 | | -sprintf(out,fmt,value); |
189 | | -if ((ret=strlen(out))>width) |
190 | | -{ |
191 | | -MemSet(ascii,'*',width-2); |
192 | | -ascii[width]=0; |
193 | | -return0; |
194 | | -} |
195 | | -strcpy(ascii,out); |
196 | | -returnret; |
197 | | -#else |
198 | | -autointexpon; |
199 | | -autointsign; |
200 | | -intavail=0; |
201 | | -char*a=NULL; |
202 | | -char*p=NULL; |
203 | | -charmode; |
204 | | -intlowercase; |
205 | | -intprec; |
206 | | - |
207 | | -/* extern char*ecvt(), *fcvt();*/ |
208 | | - |
209 | | -prec=prec1; |
210 | | -mode=format; |
211 | | -lowercase='a'-'A'; |
212 | | -if (mode >='a') |
213 | | -mode-='a'-'A'; |
214 | | -else |
215 | | -lowercase=0; |
216 | | - |
217 | | -if (mode!='E') |
218 | | -{ |
219 | | -/* try 'F' style output */ |
220 | | -p=fcvt(value,prec,&expon,&sign); |
221 | | -avail=width; |
222 | | -a=ascii; |
223 | | - |
224 | | -/* output sign */ |
225 | | -if (sign) |
226 | | -{ |
227 | | -avail--; |
228 | | -*a++='-'; |
229 | | -} |
230 | | - |
231 | | -/* output '0' before the decimal point */ |
232 | | -if (expon <=0) |
233 | | -{ |
234 | | -*a++='0'; |
235 | | -avail--; |
236 | | -} |
237 | | - |
238 | | -/* compute space length left after dec pt and fraction */ |
239 | | -avail-=prec+1; |
240 | | -if (mode=='G') |
241 | | -avail-=4; |
242 | | - |
243 | | -if (avail >=expon) |
244 | | -{ |
245 | | - |
246 | | -/* it fits. output */ |
247 | | -while (expon>0) |
248 | | -{ |
249 | | -/* output left of dp */ |
250 | | -expon--; |
251 | | -if (*p) |
252 | | -*a++=*p++; |
253 | | -else |
254 | | -*a++='0'; |
255 | | -} |
256 | | - |
257 | | -/* output fraction (right of dec pt) */ |
258 | | -avail=expon; |
259 | | -gotofrac_out; |
260 | | -} |
261 | | -/* won't fit; let's hope for G format */ |
262 | | -} |
263 | | - |
264 | | -if (mode!='F') |
265 | | -{ |
266 | | -/* try to do E style output */ |
267 | | -p=ecvt(value,prec+1,&expon,&sign); |
268 | | -avail=width-5; |
269 | | -a=ascii; |
270 | | - |
271 | | -/* output the sign */ |
272 | | -if (sign) |
273 | | -{ |
274 | | -*a++='-'; |
275 | | -avail--; |
276 | | -} |
277 | | -} |
278 | | - |
279 | | -/* check for field too small */ |
280 | | -if (mode=='F'||avail<prec) |
281 | | -{ |
282 | | -/* sorry joker, you lose */ |
283 | | -a=ascii; |
284 | | -for (avail=width;avail>0;avail--) |
285 | | -*a++='*'; |
286 | | -*a=0; |
287 | | -return0; |
288 | | -} |
289 | | - |
290 | | -/* it fits; output the number */ |
291 | | -mode='E'; |
292 | | - |
293 | | -/* output the LHS single digit */ |
294 | | -*a++=*p++; |
295 | | -expon--; |
296 | | - |
297 | | -/* output the rhs */ |
298 | | -avail=1; |
299 | | - |
300 | | -frac_out: |
301 | | -*a++='.'; |
302 | | -while (prec>0) |
303 | | -{ |
304 | | -prec--; |
305 | | -if (avail<0) |
306 | | -{ |
307 | | -avail++; |
308 | | -*a++='0'; |
309 | | -} |
310 | | -else |
311 | | -{ |
312 | | -if (*p) |
313 | | -*a++=*p++; |
314 | | -else |
315 | | -*a++='0'; |
316 | | -} |
317 | | -} |
318 | | - |
319 | | -/* output the exponent */ |
320 | | -if (mode=='E') |
321 | | -{ |
322 | | -*a++='E'+lowercase; |
323 | | -if (expon<0) |
324 | | -{ |
325 | | -*a++='-'; |
326 | | -expon=-expon; |
327 | | -} |
328 | | -else |
329 | | -*a++='+'; |
330 | | -*a++= (expon /10) %10+'0'; |
331 | | -*a++=expon %10+'0'; |
332 | | -} |
333 | | - |
334 | | -/* output spaces on the end in G format */ |
335 | | -if (mode=='G') |
336 | | -{ |
337 | | -*a++=' '; |
338 | | -*a++=' '; |
339 | | -*a++=' '; |
340 | | -*a++=' '; |
341 | | -} |
342 | | - |
343 | | -/* finally, we can return */ |
344 | | -*a=0; |
345 | | -avail=a-ascii; |
346 | | -returnavail; |
347 | | -#endif |
348 | | -} |
349 | | -#endif |
350 | | - |
351 | | -/* |
352 | | - ** atof1- ASCII TO FLOATING CONVERSION |
353 | | - ** |
354 | | - **CODE derived from ~ingres/source/gutil/atof.c |
355 | | - ** |
356 | | - **Converts the string 'str' to floating point and stores the |
357 | | - **result into the cell pointed to by 'val'. |
358 | | - ** |
359 | | - **The syntax which it accepts is pretty much what you would |
360 | | - **expect. Basically, it is: |
361 | | - **{<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>] |
362 | | - **where <exp> is "e" or "E" followed by an integer, <sp> is a |
363 | | - **space character, <digit> is zero through nine, [] is zero or |
364 | | - **one, and {} is zero or more. |
365 | | - ** |
366 | | - **Parameters: |
367 | | - **str -- string to convert. |
368 | | - **val -- pointer to place to put the result (which |
369 | | - **must be type double). |
370 | | - ** |
371 | | - **Returns: |
372 | | - **zero -- ok. |
373 | | - **-1 -- syntax error. |
374 | | - **+1 -- overflow (not implemented). |
375 | | - ** |
376 | | - **Side Effects: |
377 | | - **clobbers *val. |
378 | | - */ |
379 | | -#ifdefNOT_USED |
380 | | -int |
381 | | -atof1(char*str,double*val) |
382 | | -{ |
383 | | -char*p; |
384 | | -doublev; |
385 | | -doublefact; |
386 | | -intminus; |
387 | | -charc; |
388 | | -intexpon; |
389 | | -intgotmant; |
390 | | - |
391 | | -v=0.0; |
392 | | -p=str; |
393 | | -minus=0; |
394 | | - |
395 | | -/* skip leading blanks */ |
396 | | -while ((c=*p)!='\0') |
397 | | -{ |
398 | | -if (c!=' ') |
399 | | -break; |
400 | | -p++; |
401 | | -} |
402 | | - |
403 | | -/* handle possible sign */ |
404 | | -switch (c) |
405 | | -{ |
406 | | -case'-': |
407 | | -minus++; |
408 | | - |
409 | | -case'+': |
410 | | -p++; |
411 | | -} |
412 | | - |
413 | | -/* skip blanks after sign */ |
414 | | -while ((c=*p)!='\0') |
415 | | -{ |
416 | | -if (c!=' ') |
417 | | -break; |
418 | | -p++; |
419 | | -} |
420 | | - |
421 | | -/* start collecting the number to the decimal point */ |
422 | | -gotmant=0; |
423 | | -for (;;) |
424 | | -{ |
425 | | -c=*p; |
426 | | -if (c<'0'||c>'9') |
427 | | -break; |
428 | | -v=v*10.0+ (c-'0'); |
429 | | -gotmant++; |
430 | | -p++; |
431 | | -} |
432 | | - |
433 | | -/* check for fractional part */ |
434 | | -if (c=='.') |
435 | | -{ |
436 | | -fact=1.0; |
437 | | -for (;;) |
438 | | -{ |
439 | | -c=*++p; |
440 | | -if (c<'0'||c>'9') |
441 | | -break; |
442 | | -fact *=0.1; |
443 | | -v+= (c-'0')*fact; |
444 | | -gotmant++; |
445 | | -} |
446 | | -} |
447 | | - |
448 | | -/* skip blanks before possible exponent */ |
449 | | -while ((c=*p)!='\0') |
450 | | -{ |
451 | | -if (c!=' ') |
452 | | -break; |
453 | | -p++; |
454 | | -} |
455 | | - |
456 | | -/* test for exponent */ |
457 | | -if (c=='e'||c=='E') |
458 | | -{ |
459 | | -p++; |
460 | | -expon=pg_atoi(p,sizeof(expon),'\0'); |
461 | | -if (!gotmant) |
462 | | -v=1.0; |
463 | | -fact=expon; |
464 | | -v *=pow(10.0,fact); |
465 | | -} |
466 | | -else |
467 | | -{ |
468 | | -/* if no exponent, then nothing */ |
469 | | -if (c!=0) |
470 | | -return-1; |
471 | | -} |
472 | | - |
473 | | -/* store the result and exit */ |
474 | | -if (minus) |
475 | | -v=-v; |
476 | | -*val=v; |
477 | | -return0; |
478 | | -} |
479 | | - |
480 | | -#endif |